package com.mercury.ec.module.air.service.order;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.mercury.ec.framework.air.core.client.dto.order.cancel.AirOrderCancelReqDTO;
import com.mercury.ec.framework.air.core.client.dto.order.cancel.AirOrderCancelRespDTO;
import com.mercury.ec.framework.air.core.client.dto.order.issue.AirOrderIssuePassengerRespDTO;
import com.mercury.ec.framework.air.core.client.dto.order.issue.AirOrderIssueReqDTO;
import com.mercury.ec.framework.air.core.client.dto.order.issue.AirOrderIssueRespDTO;
import com.mercury.ec.framework.air.core.client.impl.sunstn.util.SunstnUtils;
import com.mercury.ec.framework.common.enums.*;
import com.mercury.ec.framework.common.pojo.PageResult;
import com.mercury.ec.framework.common.util.object.BeanUtils;
import com.mercury.ec.framework.mybatis.core.util.MyBatisUtils;
import com.mercury.ec.framework.security.core.util.SecurityFrameworkUtils;
import com.mercury.ec.framework.web.core.util.WebFrameworkUtils;
import com.mercury.ec.module.air.controller.admin.order.vo.order.*;
import com.mercury.ec.module.air.controller.admin.order.vo.orderpassenger.AirOrderPassengerApplyChangeReqVO;
import com.mercury.ec.module.air.controller.admin.order.vo.orderpassenger.AirOrderPassengerApplyReturnReqVO;
import com.mercury.ec.module.air.controller.admin.order.vo.orderpassenger.AirOrderPassengerRespVO;
import com.mercury.ec.module.air.controller.admin.order.vo.orderpnrlog.AirOrderPnrLogRespVO;
import com.mercury.ec.module.air.controller.admin.order.vo.orderprice.*;
import com.mercury.ec.module.air.controller.admin.order.vo.orderroute.AirOrderRouteApplyChangeReqVO;
import com.mercury.ec.module.air.controller.admin.order.vo.orderroute.AirOrderRouteApplyReturnReqVO;
import com.mercury.ec.module.air.controller.admin.order.vo.orderroute.AirOrderRouteRespVO;
import com.mercury.ec.module.air.dal.dataobject.order.*;
import com.mercury.ec.module.air.dal.mysql.order.*;
import com.mercury.ec.module.air.enums.*;
import com.mercury.ec.module.air.service.api.AirApiService;
import com.mercury.ec.module.air.util.AirOrderUtils;
import com.mercury.ec.module.basic.controller.admin.airservicefeerule.vo.rule.AirServiceFeeRuleRespVO;
import com.mercury.ec.module.basic.controller.admin.airservicefeerule.vo.rulesetting.AirServiceFeeRuleSettingRespVO;
import com.mercury.ec.module.basic.controller.admin.airservicefeerule.vo.rulesetting.AirServiceFeeRuleSettingTripTypeRespVO;
import com.mercury.ec.module.basic.controller.admin.customer.vo.CustomerRespVO;
import com.mercury.ec.module.basic.controller.admin.orderpay.vo.OrderPayRespVO;
import com.mercury.ec.module.basic.controller.admin.orderpay.vo.OrderPaySuspenseAccountReqVO;
import com.mercury.ec.module.basic.controller.admin.settleperiod.vo.SettlePeriodCalculateReqVO;
import com.mercury.ec.module.basic.controller.admin.settleperiod.vo.SettlePeriodCalculateRespVO;
import com.mercury.ec.module.basic.dal.dataobject.channel.ChannelDO;
import com.mercury.ec.module.basic.dal.dataobject.customer.CustomerDO;
import com.mercury.ec.module.basic.dal.dataobject.paysubject.PaySubjectDO;
import com.mercury.ec.module.basic.dal.dataobject.paysubject.TenantPaySubjectDO;
import com.mercury.ec.module.basic.dal.dataobject.vendor.VendorDO;
import com.mercury.ec.module.basic.dal.mysql.channel.ChannelMapper;
import com.mercury.ec.module.basic.dal.mysql.customer.CustomerMapper;
import com.mercury.ec.module.basic.dal.mysql.paysubject.PaySubjectMapper;
import com.mercury.ec.module.basic.dal.mysql.paysubject.TenantPaySubjectMapper;
import com.mercury.ec.module.basic.dal.mysql.vendor.VendorMapper;
import com.mercury.ec.module.basic.enums.BasicBizScopeTypeEnum;
import com.mercury.ec.module.basic.enums.BasicOrderPayTypeEnum;
import com.mercury.ec.module.basic.service.customer.CustomerService;
import com.mercury.ec.module.basic.service.orderpay.OrderPayService;
import com.mercury.ec.module.basic.service.settleperiod.SettlePeriodService;
import com.mercury.ec.module.system.dal.dataobject.user.AdminUserDO;
import com.mercury.ec.module.system.dal.mysql.user.AdminUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.mercury.ec.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.mercury.ec.module.air.enums.ErrorCodeConstants.*;
import static com.mercury.ec.module.basic.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS;
import static com.mercury.ec.module.basic.enums.ErrorCodeConstants.PAY_SUBJECT_NOT_EXISTS;

/**
 * 机票订单 Service 实现类
 *
 * @author hesx
 */
@Slf4j
@Service
@Validated
public class AirOrderServiceImpl implements AirOrderService {

    @Resource
    private AirOrderMapper airOrderMapper;
    @Resource
    private AirOrderRouteMapper airOrderRouteMapper;
    @Resource
    private AirOrderPassengerMapper airOrderPassengerMapper;
    @Resource
    private AirOrderPriceMapper airOrderPriceMapper;
    @Resource
    private AirOrderPnrLogMapper airOrderPnrLogMapper;
    @Resource
    private AdminUserMapper adminUserMapper;
    @Resource
    private CustomerMapper customerMapper;
    @Resource
    private TenantPaySubjectMapper tenantPaySubjectMapper;
    @Resource
    private PaySubjectMapper paySubjectMapper;
    @Resource
    private SettlePeriodService settlePeriodService;
    @Resource
    private ChannelMapper channelMapper;
    @Resource
    private VendorMapper vendorMapper;

    @Resource
    private CustomerService customerService;
    @Resource
    private AirApiService airApiService;
    @Resource
    private OrderPayService orderPayService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createOrder(AirOrderCreateReqVO createReqVO) {
        long orderId = IdWorker.getId();
        // 生成编号
        String no = AirOrderUtils.getNo(orderId, createReqVO.getType());
        // 校验
        validateOrderForCreateOrUpdate(null, no, createReqVO.getPnr());
        // 客户
        CustomerDO customerDO = Optional.ofNullable(customerMapper.selectById(createReqVO.getCustomerId())).orElseThrow(() -> exception(CUSTOMER_NOT_EXISTS));
        // 业务员
        AdminUserDO salesmanUserDO = Optional.ofNullable(adminUserMapper.selectById(createReqVO.getSalesmanUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_SALESMAN_NOT_EXISTS));
        // 预订员
        AdminUserDO bookUserDO = Optional.ofNullable(adminUserMapper.selectById(createReqVO.getBookUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_BOOK_USER_NOT_EXISTS));
//        // 配送员
//        AdminUserDO deliveryUser = Optional.ofNullable(adminUserMapper.selectById(createReqVO.getDeliveryUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_DELIVERY_USER_NOT_EXISTS));
        // 销售支付方式
        Long salePayTypeId = null;
        TenantPaySubjectDO saleTenantPaySubjectDO = tenantPaySubjectMapper.selectById(createReqVO.getSalePaySubjectId());
        if (saleTenantPaySubjectDO == null) {
            PaySubjectDO salePaySubjectDO = paySubjectMapper.selectById(createReqVO.getSalePaySubjectId());
            if (salePaySubjectDO == null) {
                throw exception(PAY_SUBJECT_NOT_EXISTS);
            }
            salePayTypeId = salePaySubjectDO.getPayTypeId();
        } else {
            salePayTypeId = saleTenantPaySubjectDO.getPayTypeId();
        }
        // 采购支付方式
        Long purchasePayTypeId = null;
        TenantPaySubjectDO purchaseTenantPaySubjectDO = tenantPaySubjectMapper.selectById(createReqVO.getSalePaySubjectId());
        if (purchaseTenantPaySubjectDO == null) {
            PaySubjectDO purchasePaySubjectDO = paySubjectMapper.selectById(createReqVO.getSalePaySubjectId());
            if (purchasePaySubjectDO == null) {
                throw exception(PAY_SUBJECT_NOT_EXISTS);
            }
            purchasePayTypeId = purchasePaySubjectDO.getPayTypeId();
        } else {
            purchasePayTypeId = saleTenantPaySubjectDO.getPayTypeId();
        }

        // 订单信息
        AirOrderDO order = BeanUtils.toBean(createReqVO, AirOrderDO.class);
        order.setId(orderId);
        order.setNo(no);
        if (ClientTypeEnum.isDistribution(createReqVO.getClientType())) {
            if (AirOrderTypeEnum.isChange(createReqVO.getType()) || AirOrderTypeEnum.isReturn(createReqVO.getType())) {
                order.setStatus(AirOrderStatusEnum.WAIT_AUDIT.getStatus());
            } else {
                order.setStatus(AirOrderStatusEnum.WAIT_PAY.getStatus());
            }
        } else {
            order.setStatus(AirOrderStatusEnum.NEW.getStatus());
        }
        order.setPnrStatus(AirPnrStatusEnum.HK.getStatus());
        order.setDeptId(bookUserDO.getDeptId());
        order.setPassengerNum(createReqVO.getPassengers().size());
        order.setCustomerNo(customerDO.getNo());
        order.setCustomerName(customerDO.getName());
        order.setSaleSettleType(customerDO.getSettleType());
        order.setSalesmanDeptId(salesmanUserDO.getDeptId());
        order.setBookUserId(bookUserDO.getId());
        order.setBookDeptId(bookUserDO.getDeptId());
        order.setDispatchUserId(bookUserDO.getId());
        order.setDispatchDeptId(bookUserDO.getDeptId());
        order.setDispatchTime(LocalDateTime.now());
//        order.setDeliveryDeptId(deliveryUser.getDeptId());
        order.setSalePayTypeId(salePayTypeId);
        order.setSalePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
        order.setSalePayOnline(false);
        order.setAuditStatus(AirOrderAuditStatusEnum.WAIT_AUDIT.getStatus());
        order.setPurchasePayTypeId(purchasePayTypeId);
        order.setPurchasePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
        order.setPurchasePayOnline(false);
        if (SettleTypeEnum.MONTHLY.getType().equals(customerDO.getSettleType()) && customerDO.getSettlePeriodId() != null) {
            SettlePeriodCalculateRespVO calculateRespVO = settlePeriodService.calculate(new SettlePeriodCalculateReqVO(customerDO.getSettlePeriodId(), order.getBookTime().toLocalDate()));
            order.setSaleReconcileDate(calculateRespVO.getReconcileDate());
            order.setSaleSettleDate(calculateRespVO.getSettleDate());
        }
//        order.setPurchaseReconcileDate(LocalDate.now()); // todo
//        order.setPurchaseSettleDate(LocalDate.now()); // todo
        order.setChangeStatus(AirOrderChangeStatusEnum.WAIT_CHANGE.getStatus());
        order.setReturnStatus(AirOrderReturnStatusEnum.WAIT_RETURN.getStatus());
        order.setAdjustStatus(AirOrderAdjustStatusEnum.WAIT_ADJUST.getStatus());

        // 行程信息
        List<AirOrderRouteDO> orderRouteDOS = BeanUtils.toBean(createReqVO.getRoutes(), AirOrderRouteDO.class);
        orderRouteDOS.forEach(p -> p.setOrderId(orderId));
        // 保存行程
        airOrderRouteMapper.insertBatch(orderRouteDOS);

        // 乘客信息
        List<AirOrderPassengerDO> airOrderPassengerDOS = BeanUtils.toBean(createReqVO.getPassengers(), AirOrderPassengerDO.class);
        airOrderPassengerDOS.forEach(p -> p.setOrderId(orderId));
        // 保存乘客
        airOrderPassengerMapper.insertBatch(airOrderPassengerDOS);

        // 价格汇总信息（销售）
        // 附加费
        BigDecimal saleAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal saleServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal saleUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal saleChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal saleReturnFee = BigDecimal.ZERO;
        // 费面价
        BigDecimal saleTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal saleUsedPrice = BigDecimal.ZERO;
        // 销售价
        BigDecimal salePrice = BigDecimal.ZERO;
        // 机建
        BigDecimal saleAirportTax = BigDecimal.ZERO;
        // 已用机建
        BigDecimal saleUsedAirportTax = BigDecimal.ZERO;
        // 燃油
        BigDecimal saleOilTax = BigDecimal.ZERO;
        // 已用燃油
        BigDecimal saleUsedOilTax = BigDecimal.ZERO;
        // 销售税
        BigDecimal saleTax = BigDecimal.ZERO;
        // 已用销售税
        BigDecimal saleUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal saleAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal saleBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal salePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal salePrizeTax = BigDecimal.ZERO;
        // 销售金额
        BigDecimal saleAmount = BigDecimal.ZERO;
        // 应收
        BigDecimal saleReceivable = BigDecimal.ZERO;

        // 价格汇总信息（采购）
        // 附加费
        BigDecimal purchaseAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal purchaseServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal purchaseUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal purchaseChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal purchaseReturnFee = BigDecimal.ZERO;
        // 票面价
        BigDecimal purchaseTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal purchaseUsedPrice = BigDecimal.ZERO;
        // 采购价
        BigDecimal purchasePrice = BigDecimal.ZERO;
        // 机建税
        BigDecimal purchaseAirportTax = BigDecimal.ZERO;
        // 已用机建税
        BigDecimal purchaseUsedAirportTax = BigDecimal.ZERO;
        // 燃油税
        BigDecimal purchaseOilTax = BigDecimal.ZERO;
        // 已用燃油税
        BigDecimal purchaseUsedOilTax = BigDecimal.ZERO;
        // 采购税
        BigDecimal purchaseTax = BigDecimal.ZERO;
        // 已用采购税
        BigDecimal purchaseUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal purchaseAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal purchaseBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal purchasePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal purchasePrizeTax = BigDecimal.ZERO;
        // 采购金额
        BigDecimal purchaseAmount = BigDecimal.ZERO;
        // 应付
        BigDecimal purchasePayable = BigDecimal.ZERO;

        // 价格信息
        List<AirOrderPriceDO> priceDOS = new ArrayList<>();
        for (AirOrderRouteDO or : orderRouteDOS) {
            for (AirOrderPassengerDO op : airOrderPassengerDOS) {
                for (AirOrderPriceCreateReqVO opr : createReqVO.getPrices()) {
                    if (or.getSerialNo().equals(opr.getRouteSerialNo()) && op.getSerialNo().equals(opr.getPassengerSerialNo())) {
                        AirOrderPriceDO orderPriceDO = BeanUtils.toBean(opr, AirOrderPriceDO.class);
                        // 关联字段
                        orderPriceDO.setOrderId(orderId);
                        orderPriceDO.setOrderRouteId(or.getId());
                        orderPriceDO.setOrderPassengerId(op.getId());
                        orderPriceDO.setChangeStatus(AirOrderChangeStatusEnum.WAIT_CHANGE.getStatus());
                        orderPriceDO.setReturnStatus(AirOrderReturnStatusEnum.WAIT_RETURN.getStatus());
                        orderPriceDO.setAdjustStatus(AirOrderAdjustStatusEnum.WAIT_ADJUST.getStatus());
                        // 基础信息
                        orderPriceDO.setPurchaseId(order.getPurchaseId());
                        orderPriceDO.setPurchaseOrderNo(order.getPurchaseOrderNo());
                        // 支付信息（销售）
                        orderPriceDO.setSalePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
                        orderPriceDO.setSalePaySubjectId(order.getSalePaySubjectId());
                        orderPriceDO.setSalePayTypeId(order.getSalePayTypeId());
                        orderPriceDO.setSalePayAccount(order.getSalePayAccount());
                        orderPriceDO.setSalePayOrderNo(order.getSalePayOrderNo());
                        orderPriceDO.setSalePayTime(order.getSalePayTime());
                        orderPriceDO.setSalePayOnline(order.getSalePayOnline());
                        // 支付信息（采购）
                        orderPriceDO.setPurchasePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
                        orderPriceDO.setPurchasePaySubjectId(order.getPurchasePaySubjectId());
                        orderPriceDO.setPurchasePayTypeId(order.getPurchasePayTypeId());
                        orderPriceDO.setPurchasePayAccount(order.getPurchasePayAccount());
                        orderPriceDO.setPurchasePayOrderNo(order.getPurchasePayOrderNo());
                        orderPriceDO.setPurchasePayTime(order.getPurchasePayTime());
                        orderPriceDO.setPurchasePayOnline(order.getPurchasePayOnline());

                        // 价格（销售）
                        // 销售金额 = 销售价 - 已用票价 + 销售税 + 升舱费 + 改期费 - 退票费
                        orderPriceDO.setSaleAmount(orderPriceDO.getSalePrice().subtract(orderPriceDO.getSaleUsedPrice()).add(orderPriceDO.getSaleTax()).add(orderPriceDO.getSaleUpgradeFee().add(orderPriceDO.getSaleChangeFee())).subtract(orderPriceDO.getSaleReturnFee()));
                        // 应收 = 销售金额 + 附加费 + 服务费
                        orderPriceDO.setSaleReceivable(orderPriceDO.getSaleAmount().add(orderPriceDO.getSaleAdditionalFee()).add(orderPriceDO.getSaleServiceFee()));
                        orderPriceDO.setSaleReceipts(BigDecimal.ZERO);
                        // 合计（销售）
                        saleAdditionalFee = saleAdditionalFee.add(orderPriceDO.getSaleAdditionalFee());
                        saleServiceFee = saleServiceFee.add(orderPriceDO.getSaleServiceFee());
                        saleUpgradeFee = saleUpgradeFee.add(orderPriceDO.getSaleUpgradeFee());
                        saleChangeFee = saleChangeFee.add(orderPriceDO.getSaleChangeFee());
                        saleReturnFee = saleReturnFee.add(orderPriceDO.getSaleReturnFee());
                        saleTicketPrice = saleTicketPrice.add(orderPriceDO.getSaleTicketPrice());
                        saleUsedPrice = saleUsedPrice.add(orderPriceDO.getSaleUsedPrice());
                        salePrice = salePrice.add(orderPriceDO.getSalePrice());
                        saleAirportTax = saleAirportTax.add(orderPriceDO.getSaleAirportTax());
                        saleUsedAirportTax = saleUsedAirportTax.add(orderPriceDO.getSaleUsedAirportTax());
                        saleOilTax = saleOilTax.add(orderPriceDO.getSaleOilTax());
                        saleUsedOilTax = saleUsedOilTax.add(orderPriceDO.getSaleUsedOilTax());
                        saleTax = saleTax.add(orderPriceDO.getSaleTax());
                        saleUsedTax = saleUsedTax.add(orderPriceDO.getSaleUsedTax());
                        saleAgencyFee = saleAgencyFee.add(orderPriceDO.getSaleAgencyFee());
                        saleBackRebateFee = saleBackRebateFee.add(orderPriceDO.getSaleBackRebateFee());
                        salePrizePrice = salePrizePrice.add(orderPriceDO.getSalePrizePrice());
                        salePrizeTax = salePrizeTax.add(orderPriceDO.getSalePrizeTax());
                        saleAmount = saleAmount.add(orderPriceDO.getSaleAmount());
                        saleReceivable = saleReceivable.add(orderPriceDO.getSaleReceivable());

                        // 价格（采购）
                        orderPriceDO.setPurchaseReturnFee(BigDecimal.ZERO);
                        // 采购金额 = 采购价 + 采购税（机建+燃油） + 升舱费 + 改期费 - 退票费
                        orderPriceDO.setPurchaseAmount(orderPriceDO.getPurchasePrice().add(orderPriceDO.getPurchaseTax()).add(orderPriceDO.getPurchaseUpgradeFee().add(orderPriceDO.getPurchaseChangeFee())).subtract(orderPriceDO.getPurchaseReturnFee()));
                        // 应付 = 采购金额 + 附加费 + 服务费
                        orderPriceDO.setPurchasePayable(orderPriceDO.getPurchaseAmount().add(orderPriceDO.getPurchaseAdditionalFee()).add(orderPriceDO.getPurchaseServiceFee()));
                        orderPriceDO.setPurchasePayment(BigDecimal.ZERO);
                        // 合计（采购）
                        purchaseAdditionalFee = purchaseAdditionalFee.add(orderPriceDO.getPurchaseAdditionalFee());
                        purchaseServiceFee = purchaseServiceFee.add(orderPriceDO.getPurchaseServiceFee());
                        purchaseUpgradeFee = purchaseUpgradeFee.add(orderPriceDO.getPurchaseUpgradeFee());
                        purchaseChangeFee = purchaseChangeFee.add(orderPriceDO.getPurchaseChangeFee());
                        purchaseReturnFee = purchaseReturnFee.add(orderPriceDO.getPurchaseReturnFee());
                        purchaseTicketPrice = purchaseTicketPrice.add(orderPriceDO.getPurchaseTicketPrice());
                        purchaseUsedPrice = purchaseUsedPrice.add(orderPriceDO.getPurchaseUsedPrice());
                        purchasePrice = purchasePrice.add(orderPriceDO.getPurchasePrice());
                        purchaseAirportTax = purchaseAirportTax.add(orderPriceDO.getPurchaseAirportTax());
                        purchaseUsedAirportTax = purchaseUsedAirportTax.add(orderPriceDO.getPurchaseUsedAirportTax());
                        purchaseOilTax = purchaseOilTax.add(orderPriceDO.getPurchaseOilTax());
                        purchaseUsedOilTax = purchaseUsedOilTax.add(orderPriceDO.getPurchaseUsedOilTax());
                        purchaseTax = purchaseTax.add(orderPriceDO.getPurchaseTax());
                        purchaseUsedTax = purchaseUsedTax.add(orderPriceDO.getPurchaseUsedTax());
                        purchaseAgencyFee = purchaseAgencyFee.add(orderPriceDO.getPurchaseAgencyFee());
                        purchaseBackRebateFee = purchaseBackRebateFee.add(orderPriceDO.getPurchaseBackRebateFee());
                        purchasePrizePrice = purchasePrizePrice.add(orderPriceDO.getPurchasePrizePrice());
                        purchasePrizeTax = purchasePrizeTax.add(orderPriceDO.getPurchasePrizeTax());
                        purchaseAmount = purchaseAmount.add(orderPriceDO.getPurchaseAmount());
                        purchasePayable = purchasePayable.add(orderPriceDO.getPurchasePayable());
                        priceDOS.add(orderPriceDO);
                    }
                }
            }
        }
        // 保存价格信息
        airOrderPriceMapper.insertBatch(priceDOS);

        // 保存PNR日志
        if (StrUtil.isNotBlank(createReqVO.getPnr()) && StrUtil.isNotBlank(createReqVO.getPnrContent())) {
            AirOrderPnrLogDO pnrLogDO = new AirOrderPnrLogDO();
            pnrLogDO.setOrderId(orderId);
            pnrLogDO.setPnr(createReqVO.getPnr());
            pnrLogDO.setContent(createReqVO.getPnrContent());
            airOrderPnrLogMapper.insert(pnrLogDO);
        }

        // 保存订单
        order.setSaleAdditionalFee(saleAdditionalFee);
        order.setSaleServiceFee(saleServiceFee);
        order.setSaleUpgradeFee(saleUpgradeFee);
        order.setSaleChangeFee(saleChangeFee);
        order.setSaleReturnFee(saleReturnFee);
        order.setSaleTicketPrice(saleTicketPrice);
        order.setSaleUsedPrice(saleUsedPrice);
        order.setSalePrice(salePrice);
        order.setSaleAirportTax(saleAirportTax);
        order.setSaleUsedAirportTax(saleUsedAirportTax);
        order.setSaleOilTax(saleOilTax);
        order.setSaleUsedOilTax(saleUsedOilTax);
        order.setSaleTax(saleTax);
        order.setSaleUsedTax(saleUsedTax);
        order.setSaleAgencyFee(saleAgencyFee);
        order.setSaleBackRebateFee(saleBackRebateFee);
        order.setSalePrizePrice(salePrizePrice);
        order.setSalePrizeTax(salePrizeTax);
        order.setSaleAmount(saleAmount);
        order.setSaleReceivable(saleReceivable);
        order.setSaleReceipts(BigDecimal.ZERO);
        order.setPurchaseAdditionalFee(purchaseAdditionalFee);
        order.setPurchaseServiceFee(purchaseServiceFee);
        order.setPurchaseUpgradeFee(purchaseUpgradeFee);
        order.setPurchaseChangeFee(purchaseChangeFee);
        order.setPurchaseReturnFee(purchaseReturnFee);
        order.setPurchaseTicketPrice(purchaseTicketPrice);
        order.setPurchaseUsedPrice(purchaseUsedPrice);
        order.setPurchasePrice(purchasePrice);
        order.setPurchaseAirportTax(purchaseAirportTax);
        order.setPurchaseOilTax(purchaseOilTax);
        order.setPurchaseTax(purchaseTax);
        order.setPurchaseUsedTax(purchaseUsedTax);
        order.setPurchaseAgencyFee(purchaseAgencyFee);
        order.setPurchaseBackRebateFee(purchaseBackRebateFee);
        order.setPurchasePrizePrice(purchasePrizePrice);
        order.setPurchasePrizeTax(purchasePrizeTax);
        order.setPurchaseAmount(purchaseAmount);
        order.setPurchasePayable(purchasePayable);
        order.setPurchasePayment(BigDecimal.ZERO);
        airOrderMapper.insert(order);
        // 返回
        return order.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateOrder(AirOrderUpdateReqVO updateReqVO) {
        // 校验
        AirOrderDO airOrderDO = validateOrderForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getNo(), updateReqVO.getPnr());
        // todo 暂不需要锁单校验
//        AdminUserDO user = adminUserMapper.selectById(WebFrameworkUtils.getLoginUserId());
//        if (!airOrderDO.getLocked()) {
//            throw exception(AIR_ORDER_NOT_LOCKER_NOT_ALLOW_UPDATE);
//        } else {
//            if (!Objects.equals(airOrderDO.getLockUserId(), user.getId())) {
//                AdminUserDO lockUser = adminUserMapper.selectById(airOrderDO.getLockUserId());
//                throw exception(AIR_ORDER_NOT_LOCKER_NOT_ALLOW_UNLOCK, lockUser.getNickname());
//            }
//        }
        AirOrderDO order = BeanUtils.toBean(updateReqVO, AirOrderDO.class);
        // 客户
        CustomerDO customerDO = Optional.ofNullable(customerMapper.selectById(updateReqVO.getCustomerId())).orElseThrow(() -> exception(CUSTOMER_NOT_EXISTS));
        // 业务员
        AdminUserDO salesmanUserDO = Optional.ofNullable(adminUserMapper.selectById(updateReqVO.getSalesmanUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_SALESMAN_NOT_EXISTS));
        // 预订员
        AdminUserDO bookUserDO = Optional.ofNullable(adminUserMapper.selectById(updateReqVO.getBookUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_BOOK_USER_NOT_EXISTS));
//        // 配送员
//        AdminUserDO deliveryUser = Optional.ofNullable(adminUserMapper.selectById(updateReqVO.getDeliveryUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_DELIVERY_USER_NOT_EXISTS));
        // 销售支付方式
        Long salePayTypeId = null;
        TenantPaySubjectDO saleTenantPaySubjectDO = tenantPaySubjectMapper.selectById(updateReqVO.getSalePaySubjectId());
        if (saleTenantPaySubjectDO == null) {
            PaySubjectDO salePaySubjectDO = paySubjectMapper.selectById(updateReqVO.getSalePaySubjectId());
            if (salePaySubjectDO == null) {
                throw exception(PAY_SUBJECT_NOT_EXISTS);
            }
            salePayTypeId = salePaySubjectDO.getPayTypeId();
        } else {
            salePayTypeId = saleTenantPaySubjectDO.getPayTypeId();
        }
        // 采购支付方式
        Long purchasePayTypeId = null;
        TenantPaySubjectDO purchaseTenantPaySubjectDO = tenantPaySubjectMapper.selectById(updateReqVO.getSalePaySubjectId());
        if (purchaseTenantPaySubjectDO == null) {
            PaySubjectDO purchasePaySubjectDO = paySubjectMapper.selectById(updateReqVO.getSalePaySubjectId());
            if (purchasePaySubjectDO == null) {
                throw exception(PAY_SUBJECT_NOT_EXISTS);
            }
            purchasePayTypeId = purchasePaySubjectDO.getPayTypeId();
        } else {
            purchasePayTypeId = saleTenantPaySubjectDO.getPayTypeId();
        }

        order.setDeptId(bookUserDO.getDeptId());
//        order.setTicketType(); todo
        order.setPassengerNum(updateReqVO.getPassengers().size());
        order.setCustomerNo(customerDO.getNo());
        order.setCustomerName(customerDO.getName());
        order.setSaleSettleType(customerDO.getSettleType());
        order.setSalesmanDeptId(salesmanUserDO.getDeptId());
        order.setBookDeptId(bookUserDO.getDeptId());
//        order.setDeliveryDeptId(deliveryUser.getDeptId());
//        order.setSalePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
        order.setSalePayTypeId(salePayTypeId);
//        order.setSalePayOnline(false);
//        order.setPurchasePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
        order.setPurchasePayTypeId(purchasePayTypeId);
//        order.setPurchasePayOnline(false);
        if (SettleTypeEnum.MONTHLY.getType().equals(customerDO.getSettleType()) && customerDO.getSettlePeriodId() != null) {
            SettlePeriodCalculateRespVO calculateRespVO = settlePeriodService.calculate(new SettlePeriodCalculateReqVO(customerDO.getSettlePeriodId(), order.getBookTime().toLocalDate()));
            order.setSaleReconcileDate(calculateRespVO.getReconcileDate());
            order.setSaleSettleDate(calculateRespVO.getSettleDate());
        }
//        order.setPurchaseReconcileDate(LocalDate.now()); // todo
//        order.setPurchaseSettleDate(LocalDate.now()); // todo

        // 删除已存在数据
        airOrderRouteMapper.deleteByOrderId(updateReqVO.getId());
        airOrderPassengerMapper.deleteByOrderId(updateReqVO.getId());
        airOrderPriceMapper.deleteByOrderId(updateReqVO.getId());

        // 行程信息
        List<AirOrderRouteDO> orderRouteDOS = BeanUtils.toBean(updateReqVO.getRoutes(), AirOrderRouteDO.class);
        orderRouteDOS.forEach(p -> p.setOrderId(order.getId()));
        // 保存行程
        airOrderRouteMapper.insertBatch(orderRouteDOS);

        // 乘客信息
        List<AirOrderPassengerDO> airOrderPassengerDOS = BeanUtils.toBean(updateReqVO.getPassengers(), AirOrderPassengerDO.class);
        airOrderPassengerDOS.forEach(p -> p.setOrderId(order.getId()));
        // 保存乘客
        airOrderPassengerMapper.insertBatch(airOrderPassengerDOS);

        // 价格汇总信息（销售）
        // 附加费
        BigDecimal saleAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal saleServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal saleUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal saleChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal saleReturnFee = BigDecimal.ZERO;
        // 费面价
        BigDecimal saleTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal saleUsedPrice = BigDecimal.ZERO;
        // 销售价
        BigDecimal salePrice = BigDecimal.ZERO;
        // 机建
        BigDecimal saleAirportTax = BigDecimal.ZERO;
        // 已用机建
        BigDecimal saleUsedAirportTax = BigDecimal.ZERO;
        // 燃油
        BigDecimal saleOilTax = BigDecimal.ZERO;
        // 已用燃油
        BigDecimal saleUsedOilTax = BigDecimal.ZERO;
        // 销售税
        BigDecimal saleTax = BigDecimal.ZERO;
        // 已用销售税
        BigDecimal saleUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal saleAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal saleBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal salePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal salePrizeTax = BigDecimal.ZERO;
        // 销售金额
        BigDecimal saleAmount = BigDecimal.ZERO;
        // 应收
        BigDecimal saleReceivable = BigDecimal.ZERO;

        // 价格汇总信息（采购）
        // 附加费
        BigDecimal purchaseAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal purchaseServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal purchaseUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal purchaseChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal purchaseReturnFee = BigDecimal.ZERO;
        // 票面价
        BigDecimal purchaseTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal purchaseUsedPrice = BigDecimal.ZERO;
        // 采购价
        BigDecimal purchasePrice = BigDecimal.ZERO;
        // 机建税
        BigDecimal purchaseAirportTax = BigDecimal.ZERO;
        // 已用机建税
        BigDecimal purchaseUsedAirportTax = BigDecimal.ZERO;
        // 燃油税
        BigDecimal purchaseOilTax = BigDecimal.ZERO;
        // 已用燃油税
        BigDecimal purchaseUsedOilTax = BigDecimal.ZERO;
        // 采购税
        BigDecimal purchaseTax = BigDecimal.ZERO;
        // 已用采购税
        BigDecimal purchaseUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal purchaseAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal purchaseBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal purchasePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal purchasePrizeTax = BigDecimal.ZERO;
        // 采购金额
        BigDecimal purchaseAmount = BigDecimal.ZERO;
        // 应付
        BigDecimal purchasePayable = BigDecimal.ZERO;

        // 价格信息
        List<AirOrderPriceDO> priceDOS = new ArrayList<>();
        for (AirOrderRouteDO or : orderRouteDOS) {
            for (AirOrderPassengerDO op : airOrderPassengerDOS) {
                for (AirOrderPriceUpdateReqVO opr : updateReqVO.getPrices()) {
                    if (or.getSerialNo().equals(opr.getRouteSerialNo()) && op.getSerialNo().equals(opr.getPassengerSerialNo())) {
                        AirOrderPriceDO orderPriceDO = BeanUtils.toBean(opr, AirOrderPriceDO.class);
                        // 关联字段
                        orderPriceDO.setOrderId(order.getId());
                        orderPriceDO.setOrderRouteId(or.getId());
                        orderPriceDO.setOrderPassengerId(op.getId());
                        orderPriceDO.setChangeStatus(AirOrderChangeStatusEnum.WAIT_CHANGE.getStatus());
                        orderPriceDO.setReturnStatus(AirOrderReturnStatusEnum.WAIT_RETURN.getStatus());
                        orderPriceDO.setAdjustStatus(AirOrderAdjustStatusEnum.WAIT_ADJUST.getStatus());
                        // 基础信息
                        orderPriceDO.setPurchaseId(order.getPurchaseId());
                        orderPriceDO.setPurchaseOrderNo(order.getPurchaseOrderNo());
                        // 支付信息（销售）
                        orderPriceDO.setSalePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
                        orderPriceDO.setSalePaySubjectId(order.getSalePaySubjectId());
                        orderPriceDO.setSalePayTypeId(order.getSalePayTypeId());
                        orderPriceDO.setSalePayAccount(order.getSalePayAccount());
                        orderPriceDO.setSalePayOrderNo(order.getSalePayOrderNo());
                        orderPriceDO.setSalePayTime(order.getSalePayTime());
                        orderPriceDO.setSalePayOnline(order.getSalePayOnline());
                        // 支付信息（采购）
                        orderPriceDO.setPurchasePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
                        orderPriceDO.setPurchasePaySubjectId(order.getPurchasePaySubjectId());
                        orderPriceDO.setPurchasePayTypeId(order.getPurchasePayTypeId());
                        orderPriceDO.setPurchasePayAccount(order.getPurchasePayAccount());
                        orderPriceDO.setPurchasePayOrderNo(order.getPurchasePayOrderNo());
                        orderPriceDO.setPurchasePayTime(order.getPurchasePayTime());
                        orderPriceDO.setPurchasePayOnline(order.getPurchasePayOnline());

                        // 不同类型处理逻辑
//                        if (AirOrderTypeEnum.isChange(order.getType())) {
//                            // 改签单
//                            orderPriceDO.setChangeUserId(order.getFinallyChangeUserId());
//                            orderPriceDO.setChangeDeptId(order.getFinallyChangeDeptId());
//                            orderPriceDO.setChangeTime(order.getFinallyChangeTime());
//                        } else if (AirOrderTypeEnum.isReturn(order.getType())) {
//                            // 退票单
//                            orderPriceDO.setReturnType(order.getFinallyReturnType());
//                            orderPriceDO.setReturnUserId(order.getFinallyReturnUserId());
//                            orderPriceDO.setReturnDeptId(order.getFinallyReturnDeptId());
//                            orderPriceDO.setReturnTime(order.getFinallyReturnTime());
//                        } else if (AirOrderTypeEnum.isAdjust(order.getType())) {
//                            // 调账单
//                            orderPriceDO.setAdjustType(null);
//                            orderPriceDO.setAdjustUserId(null);
//                            orderPriceDO.setAdjustDeptId(null);
//                            orderPriceDO.setAdjustTime(null);
//                        }

                        // 价格（销售）
                        // 销售金额 = 销售价 - 已用票价 + 销售税 + 升舱费 + 改期费 - 退票费
                        orderPriceDO.setSaleAmount(orderPriceDO.getSalePrice().subtract(orderPriceDO.getSaleUsedPrice()).add(orderPriceDO.getSaleTax()).add(orderPriceDO.getSaleUpgradeFee().add(orderPriceDO.getSaleChangeFee())).subtract(orderPriceDO.getSaleReturnFee()));
                        // 应收 = 销售金额 + 附加费 + 服务费
                        orderPriceDO.setSaleReceivable(orderPriceDO.getSaleAmount().add(orderPriceDO.getSaleAdditionalFee()).add(orderPriceDO.getSaleServiceFee()));
                        orderPriceDO.setSaleReceipts(BigDecimal.ZERO);
                        // 合计（销售）
                        saleAdditionalFee = saleAdditionalFee.add(orderPriceDO.getSaleAdditionalFee());
                        saleServiceFee = saleServiceFee.add(orderPriceDO.getSaleServiceFee());
                        saleUpgradeFee = saleUpgradeFee.add(orderPriceDO.getSaleUpgradeFee());
                        saleChangeFee = saleChangeFee.add(orderPriceDO.getSaleChangeFee());
                        saleReturnFee = saleReturnFee.add(orderPriceDO.getSaleReturnFee());
                        saleTicketPrice = saleTicketPrice.add(orderPriceDO.getSaleTicketPrice());
                        saleUsedPrice = saleUsedPrice.add(orderPriceDO.getSaleUsedPrice());
                        salePrice = salePrice.add(orderPriceDO.getSalePrice());
                        saleAirportTax = saleAirportTax.add(orderPriceDO.getSaleAirportTax());
                        saleUsedAirportTax = saleUsedAirportTax.add(orderPriceDO.getSaleUsedAirportTax());
                        saleOilTax = saleOilTax.add(orderPriceDO.getSaleOilTax());
                        saleUsedOilTax = saleUsedOilTax.add(orderPriceDO.getSaleUsedOilTax());
                        saleTax = saleTax.add(orderPriceDO.getSaleTax());
                        saleUsedTax = saleUsedTax.add(orderPriceDO.getSaleUsedTax());
                        saleAgencyFee = saleAgencyFee.add(orderPriceDO.getSaleAgencyFee());
                        saleBackRebateFee = saleBackRebateFee.add(orderPriceDO.getSaleBackRebateFee());
                        salePrizePrice = salePrizePrice.add(orderPriceDO.getSalePrizePrice());
                        salePrizeTax = salePrizeTax.add(orderPriceDO.getSalePrizeTax());
                        saleAmount = saleAmount.add(orderPriceDO.getSaleAmount());
                        saleReceivable = saleReceivable.add(orderPriceDO.getSaleReceivable());

                        // 价格（采购）
                        orderPriceDO.setPurchaseReturnFee(BigDecimal.ZERO);
                        // 采购金额 = 采购价 + 采购税（机建+燃油） + 升舱费 + 改期费 - 退票费
                        orderPriceDO.setPurchaseAmount(orderPriceDO.getPurchasePrice().add(orderPriceDO.getPurchaseTax()).add(orderPriceDO.getPurchaseUpgradeFee().add(orderPriceDO.getPurchaseChangeFee())).subtract(orderPriceDO.getPurchaseReturnFee()));
                        // 应付 = 采购金额 + 附加费 + 服务费
                        orderPriceDO.setPurchasePayable(orderPriceDO.getPurchaseAmount().add(orderPriceDO.getPurchaseAdditionalFee()).add(orderPriceDO.getPurchaseServiceFee()));
                        orderPriceDO.setPurchasePayment(BigDecimal.ZERO);
                        // 合计（采购）
                        purchaseAdditionalFee = purchaseAdditionalFee.add(orderPriceDO.getPurchaseAdditionalFee());
                        purchaseServiceFee = purchaseServiceFee.add(orderPriceDO.getPurchaseServiceFee());
                        purchaseUpgradeFee = purchaseUpgradeFee.add(orderPriceDO.getPurchaseUpgradeFee());
                        purchaseChangeFee = purchaseChangeFee.add(orderPriceDO.getPurchaseChangeFee());
                        purchaseReturnFee = purchaseReturnFee.add(orderPriceDO.getPurchaseReturnFee());
                        purchaseTicketPrice = purchaseTicketPrice.add(orderPriceDO.getPurchaseTicketPrice());
                        purchaseUsedPrice = purchaseUsedPrice.add(orderPriceDO.getPurchaseUsedPrice());
                        purchasePrice = purchasePrice.add(orderPriceDO.getPurchasePrice());
                        purchaseAirportTax = purchaseAirportTax.add(orderPriceDO.getPurchaseAirportTax());
                        purchaseUsedAirportTax = purchaseUsedAirportTax.add(orderPriceDO.getPurchaseUsedAirportTax());
                        purchaseOilTax = purchaseOilTax.add(orderPriceDO.getPurchaseOilTax());
                        purchaseUsedOilTax = purchaseUsedOilTax.add(orderPriceDO.getPurchaseUsedOilTax());
                        purchaseTax = purchaseTax.add(orderPriceDO.getPurchaseTax());
                        purchaseUsedTax = purchaseUsedTax.add(orderPriceDO.getPurchaseUsedTax());
                        purchaseAgencyFee = purchaseAgencyFee.add(orderPriceDO.getPurchaseAgencyFee());
                        purchaseBackRebateFee = purchaseBackRebateFee.add(orderPriceDO.getPurchaseBackRebateFee());
                        purchasePrizePrice = purchasePrizePrice.add(orderPriceDO.getPurchasePrizePrice());
                        purchasePrizeTax = purchasePrizeTax.add(orderPriceDO.getPurchasePrizeTax());
                        purchaseAmount = purchaseAmount.add(orderPriceDO.getPurchaseAmount());
                        purchasePayable = purchasePayable.add(orderPriceDO.getPurchasePayable());
                        priceDOS.add(orderPriceDO);
                    }
                }
            }
        }
        // 保存价格信息
        airOrderPriceMapper.insertBatch(priceDOS);

        // 保存PNR日志
        if (StrUtil.isNotBlank(updateReqVO.getPnr()) && StrUtil.isNotBlank(updateReqVO.getPnrContent())) {
            AirOrderPnrLogDO pnrLogDO = new AirOrderPnrLogDO();
            pnrLogDO.setOrderId(order.getId());
            pnrLogDO.setPnr(updateReqVO.getPnr());
            pnrLogDO.setContent(updateReqVO.getPnrContent());
            airOrderPnrLogMapper.insert(pnrLogDO);
        }

        // 保存订单
        order.setSaleAdditionalFee(saleAdditionalFee);
        order.setSaleServiceFee(saleServiceFee);
        order.setSaleUpgradeFee(saleUpgradeFee);
        order.setSaleChangeFee(saleChangeFee);
        order.setSaleReturnFee(saleReturnFee);
        order.setSaleTicketPrice(saleTicketPrice);
        order.setSaleUsedPrice(saleUsedPrice);
        order.setSalePrice(salePrice);
        order.setSaleAirportTax(saleAirportTax);
        order.setSaleUsedAirportTax(saleUsedAirportTax);
        order.setSaleOilTax(saleOilTax);
        order.setSaleUsedOilTax(saleUsedOilTax);
        order.setSaleTax(saleTax);
        order.setSaleUsedTax(saleUsedTax);
        order.setSaleAgencyFee(saleAgencyFee);
        order.setSaleBackRebateFee(saleBackRebateFee);
        order.setSalePrizePrice(salePrizePrice);
        order.setSalePrizeTax(salePrizeTax);
        order.setSaleAmount(saleAmount);
        order.setSaleReceivable(saleReceivable);
        order.setSaleReceipts(BigDecimal.ZERO);
        order.setPurchaseAdditionalFee(purchaseAdditionalFee);
        order.setPurchaseServiceFee(purchaseServiceFee);
        order.setPurchaseUpgradeFee(purchaseUpgradeFee);
        order.setPurchaseChangeFee(purchaseChangeFee);
        order.setPurchaseReturnFee(purchaseReturnFee);
        order.setPurchaseTicketPrice(purchaseTicketPrice);
        order.setPurchaseUsedPrice(purchaseUsedPrice);
        order.setPurchasePrice(purchasePrice);
        order.setPurchaseAirportTax(purchaseAirportTax);
        order.setPurchaseOilTax(purchaseOilTax);
        order.setPurchaseTax(purchaseTax);
        order.setPurchaseUsedTax(purchaseUsedTax);
        order.setPurchaseAgencyFee(purchaseAgencyFee);
        order.setPurchaseBackRebateFee(purchaseBackRebateFee);
        order.setPurchasePrizePrice(purchasePrizePrice);
        order.setPurchasePrizeTax(purchasePrizeTax);
        order.setPurchaseAmount(purchaseAmount);
        order.setPurchasePayable(purchasePayable);
        order.setPurchasePayment(BigDecimal.ZERO);
        airOrderMapper.update(order, new LambdaUpdateWrapper<AirOrderDO>()
                .set(AirOrderDO::getLocked, false)
                .set(AirOrderDO::getLockUserId, null)
                .set(AirOrderDO::getLockDeptId, null)
                .set(AirOrderDO::getLockTime, null)
                .eq(AirOrderDO::getId, order.getId()));
        // 返回
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean superUpdateOrder(AirOrderSuperUpdateReqVO superUpdateReqVO) {
        // 校验
        AirOrderDO airOrderDO = validateOrderForCreateOrUpdate(superUpdateReqVO.getId(), superUpdateReqVO.getNo(), superUpdateReqVO.getPnr());
        // todo 暂不需要锁单校验
//        AdminUserDO user = adminUserMapper.selectById(WebFrameworkUtils.getLoginUserId());
//        if (!airOrderDO.getLocked()) {
//            throw exception(AIR_ORDER_NOT_LOCKER_NOT_ALLOW_UPDATE);
//        } else {
//            if (!Objects.equals(airOrderDO.getLockUserId(), user.getId())) {
//                AdminUserDO lockUser = adminUserMapper.selectById(airOrderDO.getLockUserId());
//                throw exception(AIR_ORDER_NOT_LOCKER_NOT_ALLOW_UNLOCK, lockUser.getNickname());
//            }
//        }

        // 已收银不允许修改 todo

        AirOrderDO order = BeanUtils.toBean(superUpdateReqVO, AirOrderDO.class);
        // 当前用户
        AdminUserDO loginUser = adminUserMapper.selectById(WebFrameworkUtils.getLoginUserId());
        // 客户
        CustomerDO customerDO = Optional.ofNullable(customerMapper.selectById(superUpdateReqVO.getCustomerId())).orElseThrow(() -> exception(CUSTOMER_NOT_EXISTS));
        // 业务员
        AdminUserDO salesmanUserDO = Optional.ofNullable(adminUserMapper.selectById(superUpdateReqVO.getSalesmanUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_SALESMAN_NOT_EXISTS));
        // 预订员
        AdminUserDO bookUserDO = Optional.ofNullable(adminUserMapper.selectById(superUpdateReqVO.getBookUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_BOOK_USER_NOT_EXISTS));
//        // 配送员
//        AdminUserDO deliveryUser = Optional.ofNullable(adminUserMapper.selectById(superUpdateReqVO.getDeliveryUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_DELIVERY_USER_NOT_EXISTS));
        // 销售支付方式
        Long salePayTypeId = null;
        TenantPaySubjectDO saleTenantPaySubjectDO = tenantPaySubjectMapper.selectById(superUpdateReqVO.getSalePaySubjectId());
        if (saleTenantPaySubjectDO == null) {
            PaySubjectDO salePaySubjectDO = paySubjectMapper.selectById(superUpdateReqVO.getSalePaySubjectId());
            if (salePaySubjectDO == null) {
                throw exception(PAY_SUBJECT_NOT_EXISTS);
            }
            salePayTypeId = salePaySubjectDO.getPayTypeId();
        } else {
            salePayTypeId = saleTenantPaySubjectDO.getPayTypeId();
        }
        // 采购支付方式
        Long purchasePayTypeId = null;
        TenantPaySubjectDO purchaseTenantPaySubjectDO = tenantPaySubjectMapper.selectById(superUpdateReqVO.getSalePaySubjectId());
        if (purchaseTenantPaySubjectDO == null) {
            PaySubjectDO purchasePaySubjectDO = paySubjectMapper.selectById(superUpdateReqVO.getSalePaySubjectId());
            if (purchasePaySubjectDO == null) {
                throw exception(PAY_SUBJECT_NOT_EXISTS);
            }
            purchasePayTypeId = purchasePaySubjectDO.getPayTypeId();
        } else {
            purchasePayTypeId = saleTenantPaySubjectDO.getPayTypeId();
        }
        // 出票信息
        order.setIssueUserId(loginUser.getId());
        order.setIssueDeptId(loginUser.getDeptId());
        order.setIssueTime(LocalDateTime.now());

        order.setDeptId(loginUser.getDeptId());
//        order.setTicketType(); todo
        order.setPassengerNum(superUpdateReqVO.getPassengers().size());
        order.setCustomerNo(customerDO.getNo());
        order.setCustomerName(customerDO.getName());
        order.setSaleSettleType(customerDO.getSettleType());
        order.setSalesmanDeptId(salesmanUserDO.getDeptId());
        order.setBookDeptId(bookUserDO.getDeptId());
//        order.setDeliveryDeptId(deliveryUser.getDeptId());
//        order.setSalePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
        order.setSalePayTypeId(salePayTypeId);
//        order.setSalePayOnline(false);
//        order.setPurchasePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
        order.setPurchasePayTypeId(purchasePayTypeId);
//        order.setPurchasePayOnline(false);
        if (SettleTypeEnum.MONTHLY.getType().equals(customerDO.getSettleType()) && customerDO.getSettlePeriodId() != null) {
            SettlePeriodCalculateRespVO calculateRespVO = settlePeriodService.calculate(new SettlePeriodCalculateReqVO(customerDO.getSettlePeriodId(), order.getBookTime().toLocalDate()));
            order.setSaleReconcileDate(calculateRespVO.getReconcileDate());
            order.setSaleSettleDate(calculateRespVO.getSettleDate());
        }
//        order.setPurchaseReconcileDate(LocalDate.now()); // todo
//        order.setPurchaseSettleDate(LocalDate.now()); // todo

        // 删除已存在数据
        airOrderRouteMapper.deleteByOrderId(superUpdateReqVO.getId());
        airOrderPassengerMapper.deleteByOrderId(superUpdateReqVO.getId());
        airOrderPriceMapper.deleteByOrderId(superUpdateReqVO.getId());

        // 行程信息
        List<AirOrderRouteDO> orderRouteDOS = BeanUtils.toBean(superUpdateReqVO.getRoutes(), AirOrderRouteDO.class);
        orderRouteDOS.forEach(p -> p.setOrderId(order.getId()));
        // 保存行程
        airOrderRouteMapper.insertBatch(orderRouteDOS);

        // 乘客信息
        List<AirOrderPassengerDO> airOrderPassengerDOS = BeanUtils.toBean(superUpdateReqVO.getPassengers(), AirOrderPassengerDO.class);
        airOrderPassengerDOS.forEach(p -> p.setOrderId(order.getId()));
        // 保存乘客
        airOrderPassengerMapper.insertBatch(airOrderPassengerDOS);

        // 价格汇总信息（销售）
        // 附加费
        BigDecimal saleAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal saleServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal saleUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal saleChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal saleReturnFee = BigDecimal.ZERO;
        // 费面价
        BigDecimal saleTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal saleUsedPrice = BigDecimal.ZERO;
        // 销售价
        BigDecimal salePrice = BigDecimal.ZERO;
        // 机建
        BigDecimal saleAirportTax = BigDecimal.ZERO;
        // 已用机建
        BigDecimal saleUsedAirportTax = BigDecimal.ZERO;
        // 燃油
        BigDecimal saleOilTax = BigDecimal.ZERO;
        // 已用燃油
        BigDecimal saleUsedOilTax = BigDecimal.ZERO;
        // 销售税
        BigDecimal saleTax = BigDecimal.ZERO;
        // 已用销售税
        BigDecimal saleUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal saleAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal saleBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal salePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal salePrizeTax = BigDecimal.ZERO;
        // 销售金额
        BigDecimal saleAmount = BigDecimal.ZERO;
        // 应收
        BigDecimal saleReceivable = BigDecimal.ZERO;

        // 价格汇总信息（采购）
        // 附加费
        BigDecimal purchaseAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal purchaseServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal purchaseUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal purchaseChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal purchaseReturnFee = BigDecimal.ZERO;
        // 票面价
        BigDecimal purchaseTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal purchaseUsedPrice = BigDecimal.ZERO;
        // 采购价
        BigDecimal purchasePrice = BigDecimal.ZERO;
        // 机建税
        BigDecimal purchaseAirportTax = BigDecimal.ZERO;
        // 已用机建税
        BigDecimal purchaseUsedAirportTax = BigDecimal.ZERO;
        // 燃油税
        BigDecimal purchaseOilTax = BigDecimal.ZERO;
        // 已用燃油税
        BigDecimal purchaseUsedOilTax = BigDecimal.ZERO;
        // 采购税
        BigDecimal purchaseTax = BigDecimal.ZERO;
        // 已用采购税
        BigDecimal purchaseUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal purchaseAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal purchaseBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal purchasePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal purchasePrizeTax = BigDecimal.ZERO;
        // 采购金额
        BigDecimal purchaseAmount = BigDecimal.ZERO;
        // 应付
        BigDecimal purchasePayable = BigDecimal.ZERO;

        // 价格信息
        List<AirOrderPriceDO> priceDOS = new ArrayList<>();
        for (AirOrderRouteDO or : orderRouteDOS) {
            for (AirOrderPassengerDO op : airOrderPassengerDOS) {
                for (AirOrderPriceSuperUpdateReqVO opr : superUpdateReqVO.getPrices()) {
                    if (or.getSerialNo().equals(opr.getRouteSerialNo()) && op.getSerialNo().equals(opr.getPassengerSerialNo())) {
                        AirOrderPriceDO orderPriceDO = BeanUtils.toBean(opr, AirOrderPriceDO.class);
                        // 关联字段
                        orderPriceDO.setOrderId(order.getId());
                        orderPriceDO.setOrderRouteId(or.getId());
                        orderPriceDO.setOrderPassengerId(op.getId());
                        orderPriceDO.setChangeStatus(AirOrderChangeStatusEnum.WAIT_CHANGE.getStatus());
                        orderPriceDO.setReturnStatus(AirOrderReturnStatusEnum.WAIT_RETURN.getStatus());
                        orderPriceDO.setAdjustStatus(AirOrderAdjustStatusEnum.WAIT_ADJUST.getStatus());
                        // 基础信息
                        orderPriceDO.setPurchaseId(order.getPurchaseId());
                        orderPriceDO.setPurchaseOrderNo(order.getPurchaseOrderNo());
                        // 支付信息（销售）
                        orderPriceDO.setSalePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
                        orderPriceDO.setSalePaySubjectId(order.getSalePaySubjectId());
                        orderPriceDO.setSalePayTypeId(order.getSalePayTypeId());
                        orderPriceDO.setSalePayAccount(order.getSalePayAccount());
                        orderPriceDO.setSalePayOrderNo(order.getSalePayOrderNo());
                        orderPriceDO.setSalePayTime(order.getSalePayTime());
                        orderPriceDO.setSalePayOnline(order.getSalePayOnline());
                        // 支付信息（采购）
                        orderPriceDO.setPurchasePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
                        orderPriceDO.setPurchasePaySubjectId(order.getPurchasePaySubjectId());
                        orderPriceDO.setPurchasePayTypeId(order.getPurchasePayTypeId());
                        orderPriceDO.setPurchasePayAccount(order.getPurchasePayAccount());
                        orderPriceDO.setPurchasePayOrderNo(order.getPurchasePayOrderNo());
                        orderPriceDO.setPurchasePayTime(order.getPurchasePayTime());
                        orderPriceDO.setPurchasePayOnline(order.getPurchasePayOnline());

                        // 不同类型处理逻辑
//                        if (AirOrderTypeEnum.isChange(order.getType())) {
//                            // 改签单
//                            orderPriceDO.setChangeUserId(order.getFinallyChangeUserId());
//                            orderPriceDO.setChangeDeptId(order.getFinallyChangeDeptId());
//                            orderPriceDO.setChangeTime(order.getFinallyChangeTime());
//                        } else if (AirOrderTypeEnum.isReturn(order.getType())) {
//                            // 退票单
//                            orderPriceDO.setReturnType(order.getFinallyReturnType());
//                            orderPriceDO.setReturnUserId(order.getFinallyReturnUserId());
//                            orderPriceDO.setReturnDeptId(order.getFinallyReturnDeptId());
//                            orderPriceDO.setReturnTime(order.getFinallyReturnTime());
//                        } else if (AirOrderTypeEnum.isAdjust(order.getType())) {
//                            // 调账单
//                            orderPriceDO.setAdjustType(null);
//                            orderPriceDO.setAdjustUserId(null);
//                            orderPriceDO.setAdjustDeptId(null);
//                            orderPriceDO.setAdjustTime(null);
//                        }

                        // 价格（销售）
                        // 销售金额 = 销售价 - 已用票价 + 销售税 + 升舱费 + 改期费 - 退票费
                        orderPriceDO.setSaleAmount(orderPriceDO.getSalePrice().subtract(orderPriceDO.getSaleUsedPrice()).add(orderPriceDO.getSaleTax()).add(orderPriceDO.getSaleUpgradeFee().add(orderPriceDO.getSaleChangeFee())).subtract(orderPriceDO.getSaleReturnFee()));
                        // 应收 = 销售金额 + 附加费 + 服务费
                        orderPriceDO.setSaleReceivable(orderPriceDO.getSaleAmount().add(orderPriceDO.getSaleAdditionalFee()).add(orderPriceDO.getSaleServiceFee()));
                        orderPriceDO.setSaleReceipts(BigDecimal.ZERO);
                        // 合计（销售）
                        saleAdditionalFee = saleAdditionalFee.add(orderPriceDO.getSaleAdditionalFee());
                        saleServiceFee = saleServiceFee.add(orderPriceDO.getSaleServiceFee());
                        saleUpgradeFee = saleUpgradeFee.add(orderPriceDO.getSaleUpgradeFee());
                        saleChangeFee = saleChangeFee.add(orderPriceDO.getSaleChangeFee());
                        saleReturnFee = saleReturnFee.add(orderPriceDO.getSaleReturnFee());
                        saleTicketPrice = saleTicketPrice.add(orderPriceDO.getSaleTicketPrice());
                        saleUsedPrice = saleUsedPrice.add(orderPriceDO.getSaleUsedPrice());
                        salePrice = salePrice.add(orderPriceDO.getSalePrice());
                        saleAirportTax = saleAirportTax.add(orderPriceDO.getSaleAirportTax());
                        saleUsedAirportTax = saleUsedAirportTax.add(orderPriceDO.getSaleUsedAirportTax());
                        saleOilTax = saleOilTax.add(orderPriceDO.getSaleOilTax());
                        saleUsedOilTax = saleUsedOilTax.add(orderPriceDO.getSaleUsedOilTax());
                        saleTax = saleTax.add(orderPriceDO.getSaleTax());
                        saleUsedTax = saleUsedTax.add(orderPriceDO.getSaleUsedTax());
                        saleAgencyFee = saleAgencyFee.add(orderPriceDO.getSaleAgencyFee());
                        saleBackRebateFee = saleBackRebateFee.add(orderPriceDO.getSaleBackRebateFee());
                        salePrizePrice = salePrizePrice.add(orderPriceDO.getSalePrizePrice());
                        salePrizeTax = salePrizeTax.add(orderPriceDO.getSalePrizeTax());
                        saleAmount = saleAmount.add(orderPriceDO.getSaleAmount());
                        saleReceivable = saleReceivable.add(orderPriceDO.getSaleReceivable());

                        // 价格（采购）
                        orderPriceDO.setPurchaseReturnFee(BigDecimal.ZERO);
                        // 采购金额 = 采购价 + 采购税（机建+燃油） + 升舱费 + 改期费 - 退票费
                        orderPriceDO.setPurchaseAmount(orderPriceDO.getPurchasePrice().add(orderPriceDO.getPurchaseTax()).add(orderPriceDO.getPurchaseUpgradeFee().add(orderPriceDO.getPurchaseChangeFee())).subtract(orderPriceDO.getPurchaseReturnFee()));
                        // 应付 = 采购金额 + 附加费 + 服务费
                        orderPriceDO.setPurchasePayable(orderPriceDO.getPurchaseAmount().add(orderPriceDO.getPurchaseAdditionalFee()).add(orderPriceDO.getPurchaseServiceFee()));
                        orderPriceDO.setPurchasePayment(BigDecimal.ZERO);
                        // 合计（采购）
                        purchaseAdditionalFee = purchaseAdditionalFee.add(orderPriceDO.getPurchaseAdditionalFee());
                        purchaseServiceFee = purchaseServiceFee.add(orderPriceDO.getPurchaseServiceFee());
                        purchaseUpgradeFee = purchaseUpgradeFee.add(orderPriceDO.getPurchaseUpgradeFee());
                        purchaseChangeFee = purchaseChangeFee.add(orderPriceDO.getPurchaseChangeFee());
                        purchaseReturnFee = purchaseReturnFee.add(orderPriceDO.getPurchaseReturnFee());
                        purchaseTicketPrice = purchaseTicketPrice.add(orderPriceDO.getPurchaseTicketPrice());
                        purchaseUsedPrice = purchaseUsedPrice.add(orderPriceDO.getPurchaseUsedPrice());
                        purchasePrice = purchasePrice.add(orderPriceDO.getPurchasePrice());
                        purchaseAirportTax = purchaseAirportTax.add(orderPriceDO.getPurchaseAirportTax());
                        purchaseUsedAirportTax = purchaseUsedAirportTax.add(orderPriceDO.getPurchaseUsedAirportTax());
                        purchaseOilTax = purchaseOilTax.add(orderPriceDO.getPurchaseOilTax());
                        purchaseUsedOilTax = purchaseUsedOilTax.add(orderPriceDO.getPurchaseUsedOilTax());
                        purchaseTax = purchaseTax.add(orderPriceDO.getPurchaseTax());
                        purchaseUsedTax = purchaseUsedTax.add(orderPriceDO.getPurchaseUsedTax());
                        purchaseAgencyFee = purchaseAgencyFee.add(orderPriceDO.getPurchaseAgencyFee());
                        purchaseBackRebateFee = purchaseBackRebateFee.add(orderPriceDO.getPurchaseBackRebateFee());
                        purchasePrizePrice = purchasePrizePrice.add(orderPriceDO.getPurchasePrizePrice());
                        purchasePrizeTax = purchasePrizeTax.add(orderPriceDO.getPurchasePrizeTax());
                        purchaseAmount = purchaseAmount.add(orderPriceDO.getPurchaseAmount());
                        purchasePayable = purchasePayable.add(orderPriceDO.getPurchasePayable());
                        priceDOS.add(orderPriceDO);
                    }
                }
            }
        }
        // 保存价格信息
        airOrderPriceMapper.insertBatch(priceDOS);

        // 保存PNR日志
        if (StrUtil.isNotBlank(superUpdateReqVO.getPnr()) && StrUtil.isNotBlank(superUpdateReqVO.getPnrContent())) {
            AirOrderPnrLogDO pnrLogDO = new AirOrderPnrLogDO();
            pnrLogDO.setOrderId(order.getId());
            pnrLogDO.setPnr(superUpdateReqVO.getPnr());
            pnrLogDO.setContent(superUpdateReqVO.getPnrContent());
            airOrderPnrLogMapper.insert(pnrLogDO);
        }

        // 保存订单
        order.setSaleAdditionalFee(saleAdditionalFee);
        order.setSaleServiceFee(saleServiceFee);
        order.setSaleUpgradeFee(saleUpgradeFee);
        order.setSaleChangeFee(saleChangeFee);
        order.setSaleReturnFee(saleReturnFee);
        order.setSaleTicketPrice(saleTicketPrice);
        order.setSaleUsedPrice(saleUsedPrice);
        order.setSalePrice(salePrice);
        order.setSaleAirportTax(saleAirportTax);
        order.setSaleUsedAirportTax(saleUsedAirportTax);
        order.setSaleOilTax(saleOilTax);
        order.setSaleUsedOilTax(saleUsedOilTax);
        order.setSaleTax(saleTax);
        order.setSaleUsedTax(saleUsedTax);
        order.setSaleAgencyFee(saleAgencyFee);
        order.setSaleBackRebateFee(saleBackRebateFee);
        order.setSalePrizePrice(salePrizePrice);
        order.setSalePrizeTax(salePrizeTax);
        order.setSaleAmount(saleAmount);
        order.setSaleReceivable(saleReceivable);
        order.setSaleReceipts(BigDecimal.ZERO);
        order.setPurchaseAdditionalFee(purchaseAdditionalFee);
        order.setPurchaseServiceFee(purchaseServiceFee);
        order.setPurchaseUpgradeFee(purchaseUpgradeFee);
        order.setPurchaseChangeFee(purchaseChangeFee);
        order.setPurchaseReturnFee(purchaseReturnFee);
        order.setPurchaseTicketPrice(purchaseTicketPrice);
        order.setPurchaseUsedPrice(purchaseUsedPrice);
        order.setPurchasePrice(purchasePrice);
        order.setPurchaseAirportTax(purchaseAirportTax);
        order.setPurchaseOilTax(purchaseOilTax);
        order.setPurchaseTax(purchaseTax);
        order.setPurchaseUsedTax(purchaseUsedTax);
        order.setPurchaseAgencyFee(purchaseAgencyFee);
        order.setPurchaseBackRebateFee(purchaseBackRebateFee);
        order.setPurchasePrizePrice(purchasePrizePrice);
        order.setPurchasePrizeTax(purchasePrizeTax);
        order.setPurchaseAmount(purchaseAmount);
        order.setPurchasePayable(purchasePayable);
        order.setPurchasePayment(BigDecimal.ZERO);
        airOrderMapper.updateById(order);

        // 修改挂账记录 todo 订单金额可能发生变化，强制修改挂账信息

        // 返回
        return true;
    }

    @Override
    public void deleteOrder(Long id) {
        // 校验存在
        validateOrderExists(id);
        // 删除
        airOrderMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean confirmOrder(AirOrderConfirmReqVO confirmReqVO) {
        // 校验存在
        AirOrderDO airOrderDO = validateOrderExists(confirmReqVO.getId());
        if (AirOrderStatusEnum.isCanceled(airOrderDO.getStatus())) {
            throw exception(AIR_ORDER_CANCELED_NOT_ALLOW_CONFIRM);
        }
        if (!AirOrderStatusEnum.isNew(airOrderDO.getStatus())) {
            throw exception(AIR_ORDER_CONFIRMED_NOT_ALLOW_CONFIRM);
        }
        // 更新状态
        airOrderDO.setStatus(AirOrderStatusEnum.WAIT_ISSUE.getStatus());
        airOrderMapper.updateById(airOrderDO);
        return true;
    }

    @Override
    public AirOrderPayRespVO payOrder(AirOrderPayReqVO payReqVO) {
        // todo
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean auditOrder(AirOrderAuditReqVO auditReqVO) {
        // 校验存在
        AirOrderDO airOrderDO = validateOrderExists(auditReqVO.getId());
        if (AirOrderStatusEnum.isCanceled(airOrderDO.getStatus())) {
            throw exception(AIR_ORDER_CANCELED_NOT_ALLOW_AUDIT);
        }
        if (!AirOrderStatusEnum.isNew(airOrderDO.getStatus()) && !AirOrderStatusEnum.isWaitAudit(airOrderDO.getStatus())) {
            throw exception(AIR_ORDER_AUDITED_NOT_ALLOW_AUDIT);
        }
        AdminUserDO user = adminUserMapper.selectById(WebFrameworkUtils.getLoginUserId());
        // 更新状态
        if (AirOrderAuditStatusEnum.isRefuse(auditReqVO.getAuditStatus())) {
            airOrderDO.setStatus(AirOrderStatusEnum.REFUSED.getStatus());
        } else {
            if (ClientTypeEnum.isDistribution(airOrderDO.getClientType())) {
                airOrderDO.setStatus(AirOrderStatusEnum.WAIT_PAY.getStatus());
            } else {
                airOrderDO.setStatus(AirOrderStatusEnum.WAIT_ISSUE.getStatus());
            }
        }
        airOrderDO.setAuditStatus(auditReqVO.getAuditStatus());
        airOrderDO.setAuditRemark(auditReqVO.getAuditRemark());
        airOrderDO.setAuditUserId(user.getId());
        airOrderDO.setAuditDeptId(user.getDeptId());
        airOrderDO.setAuditTime(LocalDateTime.now());
        airOrderMapper.updateById(airOrderDO);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean issueOrder(AirOrderIssueReqVO issueReqVO) {
        // 校验存在
        AirOrderDO airOrderDO = validateOrderForCreateOrUpdate(issueReqVO.getId(), null, null);
        // 校验状态
        if (!AirOrderStatusEnum.isNew(airOrderDO.getStatus())
                && !AirOrderStatusEnum.isWaitAudit(airOrderDO.getStatus())
                && !AirOrderStatusEnum.isWaitIssue(airOrderDO.getStatus())) {
            throw exception(AIR_ORDER_ISSUED_NOT_ALLOW_ISSUED);
        }
        // 出票渠道
        ChannelDO channelDO = channelMapper.selectById(issueReqVO.getChannelId());
        if (channelDO == null) {
            throw exception(AIR_ORDER_CHANNEL_NOT_EXISTS_NOT_ALLOW_ISSUE);
        }
        if (CommonStatusEnum.isDisable(channelDO.getStatus())) {
            throw exception(AIR_ORDER_CHANNEL_DISABLED_NOT_ALLOW_ISSUE);
        }
        if (!channelDO.getApplyIssue()) {
            throw exception(AIR_ORDER_CHANNEL_NOT_APPLY_ISSUE_NOT_ALLOW_ISSUE, channelDO.getName());
        }
        if (channelDO.getPaySubjectId() == null) {
            throw exception(AIR_ORDER_CHANNEL_PAY_SUBJECT_NOT_EXISTS_NOT_ALLOW_ISSUE, channelDO.getName());
        }
        if (channelDO.getType() == null) {
            throw exception(AIR_ORDER_CHANNEL_TYPE_NOT_EXISTS_NOT_ALLOW_ISSUE, channelDO.getName());
        }
        // 出票员
        AdminUserDO issueUser = adminUserMapper.selectById(SecurityFrameworkUtils.getLoginUserId());

        // 价格汇总信息（销售）
        // 附加费
        BigDecimal saleAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal saleServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal saleUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal saleChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal saleReturnFee = BigDecimal.ZERO;
        // 费面价
        BigDecimal saleTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal saleUsedPrice = BigDecimal.ZERO;
        // 销售价
        BigDecimal salePrice = BigDecimal.ZERO;
        // 机建
        BigDecimal saleAirportTax = BigDecimal.ZERO;
        // 已用机建
        BigDecimal saleUsedAirportTax = BigDecimal.ZERO;
        // 燃油
        BigDecimal saleOilTax = BigDecimal.ZERO;
        // 已用燃油
        BigDecimal saleUsedOilTax = BigDecimal.ZERO;
        // 销售税
        BigDecimal saleTax = BigDecimal.ZERO;
        // 已用销售税
        BigDecimal saleUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal saleAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal saleBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal salePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal salePrizeTax = BigDecimal.ZERO;
        // 销售金额
        BigDecimal saleAmount = BigDecimal.ZERO;
        // 应收
        BigDecimal saleReceivable = BigDecimal.ZERO;

        // 价格汇总信息（采购）
        // 附加费
        BigDecimal purchaseAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal purchaseServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal purchaseUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal purchaseChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal purchaseReturnFee = BigDecimal.ZERO;
        // 票面价
        BigDecimal purchaseTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal purchaseUsedPrice = BigDecimal.ZERO;
        // 采购价
        BigDecimal purchasePrice = BigDecimal.ZERO;
        // 机建税
        BigDecimal purchaseAirportTax = BigDecimal.ZERO;
        // 已用机建税
        BigDecimal purchaseUsedAirportTax = BigDecimal.ZERO;
        // 燃油税
        BigDecimal purchaseOilTax = BigDecimal.ZERO;
        // 已用燃油税
        BigDecimal purchaseUsedOilTax = BigDecimal.ZERO;
        // 采购税
        BigDecimal purchaseTax = BigDecimal.ZERO;
        // 已用采购税
        BigDecimal purchaseUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal purchaseAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal purchaseBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal purchasePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal purchasePrizeTax = BigDecimal.ZERO;
        // 采购金额
        BigDecimal purchaseAmount = BigDecimal.ZERO;
        // 应付
        BigDecimal purchasePayable = BigDecimal.ZERO;

        List<AirOrderPriceDO> airOrderPriceDOS = airOrderPriceMapper.selectByOrderId(airOrderDO.getId());
        List<AirOrderRouteRespVO> airOrderRouteRespVOS = airOrderRouteMapper.selectByOrderId(airOrderDO.getId());
        List<AirOrderPassengerDO> airOrderPassengerDOS = airOrderPassengerMapper.selectByOrderId(airOrderDO.getId());
        Map<Long, AirOrderPassengerDO> airOrderPassengerMap = airOrderPassengerDOS.stream().collect(Collectors.toMap(AirOrderPassengerDO::getId, v -> v, (v1, v2) -> v1));
        // 机票服务费规则设置（默认取因公）
        CustomerRespVO customer = customerService.getCustomer(airOrderDO.getCustomerId());
        AirServiceFeeRuleRespVO airServiceFeeRule = customer.getAirServiceFeeRule();
        AirServiceFeeRuleSettingTripTypeRespVO business = Optional.ofNullable(airServiceFeeRule).map(AirServiceFeeRuleRespVO::getBusiness).orElse(new AirServiceFeeRuleSettingTripTypeRespVO());
        AirServiceFeeRuleSettingRespVO airServiceFeeRuleSetting = BasicBizScopeTypeEnum.isInternational(airOrderDO.getScopeType()) ? business.getInternation() : business.getDomestic();
        for (AirOrderPriceDO orderPriceDO : airOrderPriceDOS) {
            for (AirOrderPriceIssueReqVO opr : issueReqVO.getPrices()) {
                if (orderPriceDO.getId().equals(opr.getId())) {
                    if (!PayStatusEnum.isPaid(airOrderDO.getSalePayStatus())) {
                        // 未收银同步更新销售价格
                        orderPriceDO.setFareBasis(opr.getFareBasis());
                        orderPriceDO.setSalePrice(opr.getPurchasePrice());
                        orderPriceDO.setSaleTicketPrice(opr.getPurchaseTicketPrice());
                        orderPriceDO.setSaleAirportTax(opr.getPurchaseAirportTax());
                        orderPriceDO.setSaleOilTax(opr.getPurchaseOilTax());
                        orderPriceDO.setSaleTax(opr.getPurchaseTax());
                        // 重新计算服务费
                        AirOrderPassengerDO airOrderPassengerDO = airOrderPassengerMap.get(orderPriceDO.getOrderPassengerId());
                        orderPriceDO.setSaleServiceFee(SunstnUtils.getSaleServiceFee(airServiceFeeRuleSetting, orderPriceDO.getSaleTicketPrice().add(orderPriceDO.getSaleAirportTax()).add(orderPriceDO.getSaleOilTax()), airOrderPassengerDO.getType(), airOrderRouteRespVOS.size()));
                    }
                    // 价格（销售）
                    // 销售金额 = 销售价 - 已用票价 + 销售税 + 升舱费 + 改期费 - 退票费
                    orderPriceDO.setSaleAmount(orderPriceDO.getSalePrice().subtract(orderPriceDO.getSaleUsedPrice()).add(orderPriceDO.getSaleTax()).add(orderPriceDO.getSaleUpgradeFee().add(orderPriceDO.getSaleChangeFee())).subtract(orderPriceDO.getSaleReturnFee()));
                    // 应收 = 销售金额 + 附加费 + 服务费
                    orderPriceDO.setSaleReceivable(orderPriceDO.getSaleAmount().add(orderPriceDO.getSaleAdditionalFee()).add(orderPriceDO.getSaleServiceFee()));
                    orderPriceDO.setSaleReceipts(BigDecimal.ZERO);
                    // 合计（销售）
                    saleAdditionalFee = saleAdditionalFee.add(orderPriceDO.getSaleAdditionalFee());
                    saleServiceFee = saleServiceFee.add(orderPriceDO.getSaleServiceFee());
                    saleUpgradeFee = saleUpgradeFee.add(orderPriceDO.getSaleUpgradeFee());
                    saleChangeFee = saleChangeFee.add(orderPriceDO.getSaleChangeFee());
                    saleReturnFee = saleReturnFee.add(orderPriceDO.getSaleReturnFee());
                    saleTicketPrice = saleTicketPrice.add(orderPriceDO.getSaleTicketPrice());
                    saleUsedPrice = saleUsedPrice.add(orderPriceDO.getSaleUsedPrice());
                    salePrice = salePrice.add(orderPriceDO.getSalePrice());
                    saleAirportTax = saleAirportTax.add(orderPriceDO.getSaleAirportTax());
                    saleUsedAirportTax = saleUsedAirportTax.add(orderPriceDO.getSaleUsedAirportTax());
                    saleOilTax = saleOilTax.add(orderPriceDO.getSaleOilTax());
                    saleUsedOilTax = saleUsedOilTax.add(orderPriceDO.getSaleUsedOilTax());
                    saleTax = saleTax.add(orderPriceDO.getSaleTax());
                    saleUsedTax = saleUsedTax.add(orderPriceDO.getSaleUsedTax());
                    saleAgencyFee = saleAgencyFee.add(orderPriceDO.getSaleAgencyFee());
                    saleBackRebateFee = saleBackRebateFee.add(orderPriceDO.getSaleBackRebateFee());
                    salePrizePrice = salePrizePrice.add(orderPriceDO.getSalePrizePrice());
                    salePrizeTax = salePrizeTax.add(orderPriceDO.getSalePrizeTax());
                    saleAmount = saleAmount.add(orderPriceDO.getSaleAmount());
                    saleReceivable = saleReceivable.add(orderPriceDO.getSaleReceivable());

                    // 价格（采购）
                    orderPriceDO.setPurchaseReturnFee(BigDecimal.ZERO);
                    // 采购金额 = 采购价 + 采购税（机建+燃油） + 升舱费 + 改期费 - 退票费
                    orderPriceDO.setPurchaseAmount(orderPriceDO.getPurchasePrice().add(orderPriceDO.getPurchaseTax()).add(orderPriceDO.getPurchaseUpgradeFee().add(orderPriceDO.getPurchaseChangeFee())).subtract(orderPriceDO.getPurchaseReturnFee()));
                    // 应付 = 采购金额 + 附加费 + 服务费
                    orderPriceDO.setPurchasePayable(orderPriceDO.getPurchaseAmount().add(orderPriceDO.getPurchaseAdditionalFee()).add(orderPriceDO.getPurchaseServiceFee()));
                    orderPriceDO.setPurchasePayment(BigDecimal.ZERO);
                    // 合计（采购）
                    purchaseAdditionalFee = purchaseAdditionalFee.add(orderPriceDO.getPurchaseAdditionalFee());
                    purchaseServiceFee = purchaseServiceFee.add(orderPriceDO.getPurchaseServiceFee());
                    purchaseUpgradeFee = purchaseUpgradeFee.add(orderPriceDO.getPurchaseUpgradeFee());
                    purchaseChangeFee = purchaseChangeFee.add(orderPriceDO.getPurchaseChangeFee());
                    purchaseReturnFee = purchaseReturnFee.add(orderPriceDO.getPurchaseReturnFee());
                    purchaseTicketPrice = purchaseTicketPrice.add(orderPriceDO.getPurchaseTicketPrice());
                    purchaseUsedPrice = purchaseUsedPrice.add(orderPriceDO.getPurchaseUsedPrice());
                    purchasePrice = purchasePrice.add(orderPriceDO.getPurchasePrice());
                    purchaseAirportTax = purchaseAirportTax.add(orderPriceDO.getPurchaseAirportTax());
                    purchaseUsedAirportTax = purchaseUsedAirportTax.add(orderPriceDO.getPurchaseUsedAirportTax());
                    purchaseOilTax = purchaseOilTax.add(orderPriceDO.getPurchaseOilTax());
                    purchaseUsedOilTax = purchaseUsedOilTax.add(orderPriceDO.getPurchaseUsedOilTax());
                    purchaseTax = purchaseTax.add(orderPriceDO.getPurchaseTax());
                    purchaseUsedTax = purchaseUsedTax.add(orderPriceDO.getPurchaseUsedTax());
//                    purchaseAgencyFee = purchaseAgencyFee.add(orderPriceDO.getPurchaseAgencyFee());
                    purchaseBackRebateFee = purchaseBackRebateFee.add(orderPriceDO.getPurchaseBackRebateFee());
                    purchasePrizePrice = purchasePrizePrice.add(orderPriceDO.getPurchasePrizePrice());
                    purchasePrizeTax = purchasePrizeTax.add(orderPriceDO.getPurchasePrizeTax());
                    purchaseAmount = purchaseAmount.add(orderPriceDO.getPurchaseAmount());
                    purchasePayable = purchasePayable.add(orderPriceDO.getPurchasePayable());
                    // 更新价格
                    airOrderPriceMapper.updateById(orderPriceDO);
                }
            }
        }

        // 调接口出票
        AirOrderIssueReqDTO airOrderIssueReqDTO = new AirOrderIssueReqDTO();
        airOrderIssueReqDTO.setChannelId(issueReqVO.getChannelId());
        airOrderIssueReqDTO.setPnr(airOrderDO.getPnr());
        airOrderIssueReqDTO.setFareBasis(airOrderPriceDOS.get(0).getFareBasis());
        airOrderIssueReqDTO.setCustomerAgreementNo(issueReqVO.getCustomerAgreementNo());
        airOrderIssueReqDTO.setScopeType(airOrderDO.getScopeType());
        airOrderIssueReqDTO.setAmount(airOrderDO.getPurchaseAmount());
        AirOrderIssueRespDTO airOrderIssueRespDTO = airApiService.issueOrder(airOrderIssueReqDTO);
        if (airOrderIssueRespDTO.getSuccess()) {
            // 更新票号
            if (CollUtil.isNotEmpty(airOrderIssueRespDTO.getPassengers())) {
                Map<String, AirOrderIssuePassengerRespDTO> issuePassengerMap = airOrderIssueRespDTO.getPassengers().stream().collect(Collectors.toMap(k -> k.getCardType() + k.getCardNo(), v -> v, (v1, v2) -> v1));
                Map<Long, AirOrderPassengerDO> passengerMap = airOrderPassengerDOS.stream().collect(Collectors.toMap(k -> k.getId(), v -> v, (v1, v2) -> v1));
                for (AirOrderPriceDO orderPriceDO : airOrderPriceDOS) {
                    // 更新票号
                    AirOrderPassengerDO airOrderPassengerDO = passengerMap.get(orderPriceDO.getOrderPassengerId());
                    if (airOrderPassengerDO != null) {
                        AirOrderIssuePassengerRespDTO airOrderIssuePassengerRespDTO = issuePassengerMap.get(airOrderPassengerDO.getCardType() + airOrderPassengerDO.getCardNo());
                        airOrderPriceMapper.update(new LambdaUpdateWrapper<AirOrderPriceDO>()
                                .set(AirOrderPriceDO::getAirlineIssueNo, airOrderIssuePassengerRespDTO.getAirlineIssueNo())
                                .set(AirOrderPriceDO::getTicketNo, airOrderIssuePassengerRespDTO.getTicketNo())
                                .set(AirOrderPriceDO::getTicketLastNo, airOrderIssuePassengerRespDTO.getTicketLastNo())
                                .eq(AirOrderPriceDO::getId, orderPriceDO.getId()));
                    }
                }
            }


            // 更新代理费，代理费写到第一航段
            Map<Long, AirOrderRouteRespVO> routeMap = airOrderRouteRespVOS.stream().collect(Collectors.toMap(k -> k.getId(), v -> v, (v1, v2) -> v1));
            for (AirOrderPriceDO orderPriceDO : airOrderPriceDOS) {
                AirOrderRouteRespVO airOrderRouteRespVO = routeMap.get(orderPriceDO.getOrderRouteId());
                if (airOrderRouteRespVO != null) {
                    if (airOrderRouteRespVO.getSerialNo() == 1) {
                        if (BasicBizScopeTypeEnum.isDomestic(airOrderDO.getScopeType())) {
                            orderPriceDO.setPurchaseAgencyFee(airOrderIssueRespDTO.getAgencyFee());
                        } else if (BasicBizScopeTypeEnum.isInternational(airOrderDO.getScopeType())) {
                            orderPriceDO.setPurchaseAgencyFeeRate(airOrderIssueRespDTO.getAgencyFee().divide(BigDecimal.valueOf(100)));
                            orderPriceDO.setPurchaseAgencyFee(orderPriceDO.getPurchaseTicketPrice().multiply(orderPriceDO.getPurchaseAgencyFeeRate()));
                            orderPriceDO.setPurchasePrice(orderPriceDO.getPurchaseTicketPrice().subtract(orderPriceDO.getPurchaseAgencyFee()));
                        }
                        purchaseAgencyFee = purchaseAgencyFee.add(orderPriceDO.getPurchaseAgencyFee());
                        airOrderPriceMapper.update(new LambdaUpdateWrapper<AirOrderPriceDO>()
                                .set(AirOrderPriceDO::getPurchaseAgencyFeeRate, orderPriceDO.getPurchaseAgencyFeeRate())
                                .set(AirOrderPriceDO::getPurchaseAgencyFee, orderPriceDO.getPurchaseAgencyFee())
                                .set(AirOrderPriceDO::getPurchasePrice, orderPriceDO.getPurchasePrice())
                                .eq(AirOrderPriceDO::getId, orderPriceDO.getId()));
                    }
                }
            }

            // 更新出票信息
            if (StrUtil.isNotBlank(airOrderIssueRespDTO.getIssueOffice())) {
                airOrderDO.setIssueOffice(airOrderIssueRespDTO.getIssueOffice());
                VendorDO vendorDO = vendorMapper.selectByIssueOffice(airOrderDO.getIssueOffice());
                if (vendorDO != null) {
                    airOrderDO.setPurchaseId(vendorDO.getId());
                } else {
                    log.error("机票半自动出票，编码【{}】office号【{}】客户【{}】，未找到采购商", airOrderDO.getPnr(), airOrderDO.getIssueOffice(), airOrderDO.getCustomerNo());
                }
            }

            // 保存PNR日志
            if (StrUtil.isNotBlank(airOrderIssueRespDTO.getPnrContent())) {
                AirOrderPnrLogDO airOrderPnrLogDO = new AirOrderPnrLogDO();
                airOrderPnrLogDO.setOrderId(airOrderDO.getId());
                airOrderPnrLogDO.setPnr(airOrderIssueRespDTO.getPnr());
                airOrderPnrLogDO.setContent(airOrderIssueRespDTO.getPnrContent());
                airOrderPnrLogMapper.insert(airOrderPnrLogDO);
            }

            // 保存订单信息
            airOrderDO.setStatus(AirOrderStatusEnum.ISSUED.getStatus());
            airOrderDO.setPnrStatus(airOrderIssueRespDTO.getPnrStatus());
        } else {
            airOrderDO.setStatus(AirOrderStatusEnum.ISSUE_FAIL.getStatus());
        }

        // 更新订单
        airOrderDO.setBigPnr(airOrderIssueRespDTO.getBigPnr());
        airOrderDO.setIssueUserId(issueUser.getId());
        airOrderDO.setIssueDeptId(issueUser.getDeptId());
        airOrderDO.setIssueTime(LocalDateTime.now());
        airOrderDO.setTicketType(channelDO.getType());
        airOrderDO.setPurchasePaySubjectId(channelDO.getPaySubjectId());
        airOrderDO.setCustomerAgreementNo(issueReqVO.getCustomerAgreementNo());
        airOrderDO.setSaleAdditionalFee(saleAdditionalFee);
        airOrderDO.setSaleServiceFee(saleServiceFee);
        airOrderDO.setSaleUpgradeFee(saleUpgradeFee);
        airOrderDO.setSaleChangeFee(saleChangeFee);
        airOrderDO.setSaleReturnFee(saleReturnFee);
        airOrderDO.setSaleTicketPrice(saleTicketPrice);
        airOrderDO.setSaleUsedPrice(saleUsedPrice);
        airOrderDO.setSalePrice(salePrice);
        airOrderDO.setSaleAirportTax(saleAirportTax);
        airOrderDO.setSaleUsedAirportTax(saleUsedAirportTax);
        airOrderDO.setSaleOilTax(saleOilTax);
        airOrderDO.setSaleUsedOilTax(saleUsedOilTax);
        airOrderDO.setSaleTax(saleTax);
        airOrderDO.setSaleUsedTax(saleUsedTax);
        airOrderDO.setSaleAgencyFee(saleAgencyFee);
        airOrderDO.setSaleBackRebateFee(saleBackRebateFee);
        airOrderDO.setSalePrizePrice(salePrizePrice);
        airOrderDO.setSalePrizeTax(salePrizeTax);
        airOrderDO.setSaleAmount(saleAmount);
        airOrderDO.setSaleReceivable(saleReceivable);
        airOrderDO.setSaleReceipts(BigDecimal.ZERO);
        airOrderDO.setPurchaseAdditionalFee(purchaseAdditionalFee);
        airOrderDO.setPurchaseServiceFee(purchaseServiceFee);
        airOrderDO.setPurchaseUpgradeFee(purchaseUpgradeFee);
        airOrderDO.setPurchaseChangeFee(purchaseChangeFee);
        airOrderDO.setPurchaseReturnFee(purchaseReturnFee);
        airOrderDO.setPurchaseTicketPrice(purchaseTicketPrice);
        airOrderDO.setPurchaseUsedPrice(purchaseUsedPrice);
        airOrderDO.setPurchasePrice(purchasePrice);
        airOrderDO.setPurchaseAirportTax(purchaseAirportTax);
        airOrderDO.setPurchaseOilTax(purchaseOilTax);
        airOrderDO.setPurchaseTax(purchaseTax);
        airOrderDO.setPurchaseUsedTax(purchaseUsedTax);
        airOrderDO.setPurchaseAgencyFee(purchaseAgencyFee);
        airOrderDO.setPurchaseBackRebateFee(purchaseBackRebateFee);
        airOrderDO.setPurchasePrizePrice(purchasePrizePrice);
        airOrderDO.setPurchasePrizeTax(purchasePrizeTax);
        airOrderDO.setPurchaseAmount(purchaseAmount);
        airOrderDO.setPurchasePayable(purchasePayable);
        airOrderDO.setPurchasePayment(BigDecimal.ZERO);
        airOrderMapper.updateById(airOrderDO);

        // 订单挂账
        OrderPaySuspenseAccountReqVO orderPaySuspenseAccountReqVO = new OrderPaySuspenseAccountReqVO();
        orderPaySuspenseAccountReqVO.setCustomerId(airOrderDO.getCustomerId());
        orderPaySuspenseAccountReqVO.setPayUserId(airOrderDO.getIssueUserId());
        orderPaySuspenseAccountReqVO.setProductType(ProductTypeEnum.AIR.getType());
        orderPaySuspenseAccountReqVO.setOrderId(airOrderDO.getId());
        orderPaySuspenseAccountReqVO.setOrderNo(airOrderDO.getNo());
        if (AirOrderTypeEnum.isReturn(airOrderDO.getType())) {
            orderPaySuspenseAccountReqVO.setType(BasicOrderPayTypeEnum.REFUND.getType());
        } else {
            orderPaySuspenseAccountReqVO.setType(BasicOrderPayTypeEnum.RECEIVABLE.getType());
        }
        orderPaySuspenseAccountReqVO.setAmount(airOrderDO.getSaleReceivable());
        orderPaySuspenseAccountReqVO.setPayTime(LocalDateTime.now());
        orderPaySuspenseAccountReqVO.setRemark(null);
        orderPayService.suspenseAccount(orderPaySuspenseAccountReqVO);
        // 返回
        return true;
    }

    @Override
    public Boolean refuseIssueOrder(AirOrderRefuseIssueReqVO refuseIssueReqVO) {
        // 校验存在
        AirOrderDO airOrderDO = validateOrderExists(refuseIssueReqVO.getId());
        if (!AirOrderStatusEnum.isWaitIssue(airOrderDO.getStatus())) {
            throw exception(AIR_ORDER_NOT_WAIT_ISSUE_NOT_ALLOW_REFUSE_ISSUE);
        }
        AdminUserDO loginUser = adminUserMapper.selectById(SecurityFrameworkUtils.getLoginUserId());
        airOrderDO.setStatus(AirOrderStatusEnum.ISSUE_FAIL.getStatus());
        airOrderDO.setRefuseCause(refuseIssueReqVO.getRefuseCause());
        airOrderDO.setRefuseUserId(loginUser.getId());
        airOrderDO.setRefuseDeptId(loginUser.getDeptId());
        airOrderDO.setRefuseTime(LocalDateTime.now());
        airOrderMapper.updateById(airOrderDO);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean issuedOrder(AirOrderIssuedReqVO issuedReqVO) {
        // 校验存在
        AirOrderDO airOrderDO = validateOrderForCreateOrUpdate(issuedReqVO.getId(), issuedReqVO.getNo(), issuedReqVO.getPnr());
        // 校验状态
        if (!AirOrderStatusEnum.isNew(airOrderDO.getStatus())
                && !AirOrderStatusEnum.isWaitAudit(airOrderDO.getStatus())
                && !AirOrderStatusEnum.isWaitPay(airOrderDO.getStatus())
                && !AirOrderStatusEnum.isWaitIssue(airOrderDO.getStatus())) {
            throw exception(AIR_ORDER_ISSUED_NOT_ALLOW_ISSUED);
        }

        AirOrderDO order = BeanUtils.toBean(issuedReqVO, AirOrderDO.class);
        // 出票员
        AdminUserDO issueUser = adminUserMapper.selectById(issuedReqVO.getIssueUserId());
        // 客户
        CustomerDO customerDO = Optional.ofNullable(customerMapper.selectById(issuedReqVO.getCustomerId())).orElseThrow(() -> exception(CUSTOMER_NOT_EXISTS));
        // 业务员
        AdminUserDO salesmanUserDO = Optional.ofNullable(adminUserMapper.selectById(issuedReqVO.getSalesmanUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_SALESMAN_NOT_EXISTS));
        // 预订员
        AdminUserDO bookUserDO = Optional.ofNullable(adminUserMapper.selectById(issuedReqVO.getBookUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_BOOK_USER_NOT_EXISTS));
//        // 配送员
//        AdminUserDO deliveryUser = Optional.ofNullable(adminUserMapper.selectById(issuedReqVO.getDeliveryUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_DELIVERY_USER_NOT_EXISTS));
        // 销售支付方式
        Long salePayTypeId = null;
        TenantPaySubjectDO saleTenantPaySubjectDO = tenantPaySubjectMapper.selectById(issuedReqVO.getSalePaySubjectId());
        if (saleTenantPaySubjectDO == null) {
            PaySubjectDO salePaySubjectDO = paySubjectMapper.selectById(issuedReqVO.getSalePaySubjectId());
            if (salePaySubjectDO == null) {
                throw exception(PAY_SUBJECT_NOT_EXISTS);
            }
            salePayTypeId = salePaySubjectDO.getPayTypeId();
        } else {
            salePayTypeId = saleTenantPaySubjectDO.getPayTypeId();
        }
        // 采购支付方式
        Long purchasePayTypeId = null;
        TenantPaySubjectDO purchaseTenantPaySubjectDO = tenantPaySubjectMapper.selectById(issuedReqVO.getSalePaySubjectId());
        if (purchaseTenantPaySubjectDO == null) {
            PaySubjectDO purchasePaySubjectDO = paySubjectMapper.selectById(issuedReqVO.getSalePaySubjectId());
            if (purchasePaySubjectDO == null) {
                throw exception(PAY_SUBJECT_NOT_EXISTS);
            }
            purchasePayTypeId = purchasePaySubjectDO.getPayTypeId();
        } else {
            purchasePayTypeId = saleTenantPaySubjectDO.getPayTypeId();
        }

        order.setStatus(AirOrderStatusEnum.ISSUED.getStatus());
        order.setPnrStatus(AirPnrStatusEnum.RR.getStatus());
        order.setIssueUserId(issueUser.getId());
        order.setIssueDeptId(issueUser.getDeptId());
//        order.setIssueTime(LocalDateTime.now());
//        order.setDeptId(issueUser.getDeptId());
//        order.setTicketType(); todo
        order.setPassengerNum(issuedReqVO.getPassengers().size());
        order.setCustomerNo(customerDO.getNo());
        order.setCustomerName(customerDO.getName());
        order.setSaleSettleType(customerDO.getSettleType());
        order.setSalesmanDeptId(salesmanUserDO.getDeptId());
        order.setBookDeptId(bookUserDO.getDeptId());
//        order.setDeliveryDeptId(deliveryUser.getDeptId());
//        order.setSalePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
        order.setSalePayTypeId(salePayTypeId);
//        order.setSalePayOnline(false);
//        order.setPurchasePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
        order.setPurchasePayTypeId(purchasePayTypeId);
//        order.setPurchasePayOnline(false);
        if (SettleTypeEnum.MONTHLY.getType().equals(customerDO.getSettleType()) && customerDO.getSettlePeriodId() != null) {
            SettlePeriodCalculateRespVO calculateRespVO = settlePeriodService.calculate(new SettlePeriodCalculateReqVO(customerDO.getSettlePeriodId(), order.getBookTime().toLocalDate()));
            order.setSaleReconcileDate(calculateRespVO.getReconcileDate());
            order.setSaleSettleDate(calculateRespVO.getSettleDate());
        }
//        order.setPurchaseReconcileDate(LocalDate.now()); // todo
//        order.setPurchaseSettleDate(LocalDate.now()); // todo

        // 删除已存在数据
        airOrderRouteMapper.deleteByOrderId(issuedReqVO.getId());
        airOrderPassengerMapper.deleteByOrderId(issuedReqVO.getId());
        airOrderPriceMapper.deleteByOrderId(issuedReqVO.getId());

        // 行程信息
        List<AirOrderRouteDO> orderRouteDOS = BeanUtils.toBean(issuedReqVO.getRoutes(), AirOrderRouteDO.class);
        orderRouteDOS.forEach(p -> p.setOrderId(order.getId()));
        // 保存行程
        airOrderRouteMapper.insertBatch(orderRouteDOS);

        // 乘客信息
        List<AirOrderPassengerDO> airOrderPassengerDOS = BeanUtils.toBean(issuedReqVO.getPassengers(), AirOrderPassengerDO.class);
        airOrderPassengerDOS.forEach(p -> p.setOrderId(order.getId()));
        // 保存乘客
        airOrderPassengerMapper.insertBatch(airOrderPassengerDOS);

        // 价格汇总信息（销售）
        // 附加费
        BigDecimal saleAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal saleServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal saleUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal saleChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal saleReturnFee = BigDecimal.ZERO;
        // 费面价
        BigDecimal saleTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal saleUsedPrice = BigDecimal.ZERO;
        // 销售价
        BigDecimal salePrice = BigDecimal.ZERO;
        // 机建
        BigDecimal saleAirportTax = BigDecimal.ZERO;
        // 已用机建
        BigDecimal saleUsedAirportTax = BigDecimal.ZERO;
        // 燃油
        BigDecimal saleOilTax = BigDecimal.ZERO;
        // 已用燃油
        BigDecimal saleUsedOilTax = BigDecimal.ZERO;
        // 销售税
        BigDecimal saleTax = BigDecimal.ZERO;
        // 已用销售税
        BigDecimal saleUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal saleAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal saleBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal salePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal salePrizeTax = BigDecimal.ZERO;
        // 销售金额
        BigDecimal saleAmount = BigDecimal.ZERO;
        // 应收
        BigDecimal saleReceivable = BigDecimal.ZERO;

        // 价格汇总信息（采购）
        // 附加费
        BigDecimal purchaseAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal purchaseServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal purchaseUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal purchaseChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal purchaseReturnFee = BigDecimal.ZERO;
        // 票面价
        BigDecimal purchaseTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal purchaseUsedPrice = BigDecimal.ZERO;
        // 采购价
        BigDecimal purchasePrice = BigDecimal.ZERO;
        // 机建税
        BigDecimal purchaseAirportTax = BigDecimal.ZERO;
        // 已用机建税
        BigDecimal purchaseUsedAirportTax = BigDecimal.ZERO;
        // 燃油税
        BigDecimal purchaseOilTax = BigDecimal.ZERO;
        // 已用燃油税
        BigDecimal purchaseUsedOilTax = BigDecimal.ZERO;
        // 采购税
        BigDecimal purchaseTax = BigDecimal.ZERO;
        // 已用采购税
        BigDecimal purchaseUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal purchaseAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal purchaseBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal purchasePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal purchasePrizeTax = BigDecimal.ZERO;
        // 采购金额
        BigDecimal purchaseAmount = BigDecimal.ZERO;
        // 应付
        BigDecimal purchasePayable = BigDecimal.ZERO;

        // 价格信息
        List<AirOrderPriceDO> priceDOS = new ArrayList<>();
        for (AirOrderRouteDO or : orderRouteDOS) {
            for (AirOrderPassengerDO op : airOrderPassengerDOS) {
                for (AirOrderPriceIssuedReqVO opr : issuedReqVO.getPrices()) {
                    if (or.getSerialNo().equals(opr.getRouteSerialNo()) && op.getSerialNo().equals(opr.getPassengerSerialNo())) {
                        AirOrderPriceDO orderPriceDO = BeanUtils.toBean(opr, AirOrderPriceDO.class);
                        // 关联字段
                        orderPriceDO.setOrderId(order.getId());
                        orderPriceDO.setOrderRouteId(or.getId());
                        orderPriceDO.setOrderPassengerId(op.getId());
                        orderPriceDO.setChangeStatus(AirOrderChangeStatusEnum.WAIT_CHANGE.getStatus());
                        orderPriceDO.setReturnStatus(AirOrderReturnStatusEnum.WAIT_RETURN.getStatus());
                        orderPriceDO.setAdjustStatus(AirOrderAdjustStatusEnum.WAIT_ADJUST.getStatus());
                        // 基础信息
                        orderPriceDO.setPurchaseId(order.getPurchaseId());
                        orderPriceDO.setPurchaseOrderNo(order.getPurchaseOrderNo());
                        // 支付信息（销售）
                        orderPriceDO.setSalePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
                        orderPriceDO.setSalePaySubjectId(order.getSalePaySubjectId());
                        orderPriceDO.setSalePayTypeId(order.getSalePayTypeId());
                        orderPriceDO.setSalePayAccount(order.getSalePayAccount());
                        orderPriceDO.setSalePayOrderNo(order.getSalePayOrderNo());
                        orderPriceDO.setSalePayTime(order.getSalePayTime());
                        orderPriceDO.setSalePayOnline(order.getSalePayOnline());
                        // 支付信息（采购）
                        orderPriceDO.setPurchasePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
                        orderPriceDO.setPurchasePaySubjectId(order.getPurchasePaySubjectId());
                        orderPriceDO.setPurchasePayTypeId(order.getPurchasePayTypeId());
                        orderPriceDO.setPurchasePayAccount(order.getPurchasePayAccount());
                        orderPriceDO.setPurchasePayOrderNo(order.getPurchasePayOrderNo());
                        orderPriceDO.setPurchasePayTime(order.getPurchasePayTime());
                        orderPriceDO.setPurchasePayOnline(order.getPurchasePayOnline());

                        // 不同类型处理逻辑
//                        if (AirOrderTypeEnum.isChange(order.getType())) {
//                            // 改签单
//                            orderPriceDO.setChangeUserId(order.getFinallyChangeUserId());
//                            orderPriceDO.setChangeDeptId(order.getFinallyChangeDeptId());
//                            orderPriceDO.setChangeTime(order.getFinallyChangeTime());
//                        } else if (AirOrderTypeEnum.isReturn(order.getType())) {
//                            // 退票单
//                            orderPriceDO.setReturnType(order.getFinallyReturnType());
//                            orderPriceDO.setReturnUserId(order.getFinallyReturnUserId());
//                            orderPriceDO.setReturnDeptId(order.getFinallyReturnDeptId());
//                            orderPriceDO.setReturnTime(order.getFinallyReturnTime());
//                        } else if (AirOrderTypeEnum.isAdjust(order.getType())) {
//                            // 调账单
//                            orderPriceDO.setAdjustType(null);
//                            orderPriceDO.setAdjustUserId(null);
//                            orderPriceDO.setAdjustDeptId(null);
//                            orderPriceDO.setAdjustTime(null);
//                        }

                        // 价格（销售）
                        // 销售金额 = 销售价 - 已用票价 + 销售税 + 升舱费 + 改期费 - 退票费
                        orderPriceDO.setSaleAmount(orderPriceDO.getSalePrice().subtract(orderPriceDO.getSaleUsedPrice()).add(orderPriceDO.getSaleTax()).add(orderPriceDO.getSaleUpgradeFee().add(orderPriceDO.getSaleChangeFee())).subtract(orderPriceDO.getSaleReturnFee()));
                        // 应收 = 销售金额 + 附加费 + 服务费
                        orderPriceDO.setSaleReceivable(orderPriceDO.getSaleAmount().add(orderPriceDO.getSaleAdditionalFee()).add(orderPriceDO.getSaleServiceFee()));
                        orderPriceDO.setSaleReceipts(BigDecimal.ZERO);
                        // 合计（销售）
                        saleAdditionalFee = saleAdditionalFee.add(orderPriceDO.getSaleAdditionalFee());
                        saleServiceFee = saleServiceFee.add(orderPriceDO.getSaleServiceFee());
                        saleUpgradeFee = saleUpgradeFee.add(orderPriceDO.getSaleUpgradeFee());
                        saleChangeFee = saleChangeFee.add(orderPriceDO.getSaleChangeFee());
                        saleReturnFee = saleReturnFee.add(orderPriceDO.getSaleReturnFee());
                        saleTicketPrice = saleTicketPrice.add(orderPriceDO.getSaleTicketPrice());
                        saleUsedPrice = saleUsedPrice.add(orderPriceDO.getSaleUsedPrice());
                        salePrice = salePrice.add(orderPriceDO.getSalePrice());
                        saleAirportTax = saleAirportTax.add(orderPriceDO.getSaleAirportTax());
                        saleUsedAirportTax = saleUsedAirportTax.add(orderPriceDO.getSaleUsedAirportTax());
                        saleOilTax = saleOilTax.add(orderPriceDO.getSaleOilTax());
                        saleUsedOilTax = saleUsedOilTax.add(orderPriceDO.getSaleUsedOilTax());
                        saleTax = saleTax.add(orderPriceDO.getSaleTax());
                        saleUsedTax = saleUsedTax.add(orderPriceDO.getSaleUsedTax());
                        saleAgencyFee = saleAgencyFee.add(orderPriceDO.getSaleAgencyFee());
                        saleBackRebateFee = saleBackRebateFee.add(orderPriceDO.getSaleBackRebateFee());
                        salePrizePrice = salePrizePrice.add(orderPriceDO.getSalePrizePrice());
                        salePrizeTax = salePrizeTax.add(orderPriceDO.getSalePrizeTax());
                        saleAmount = saleAmount.add(orderPriceDO.getSaleAmount());
                        saleReceivable = saleReceivable.add(orderPriceDO.getSaleReceivable());

                        // 价格（采购）
                        orderPriceDO.setPurchaseReturnFee(BigDecimal.ZERO);
                        // 采购金额 = 采购价 + 采购税（机建+燃油） + 升舱费 + 改期费 - 退票费
                        orderPriceDO.setPurchaseAmount(orderPriceDO.getPurchasePrice().add(orderPriceDO.getPurchaseTax()).add(orderPriceDO.getPurchaseUpgradeFee().add(orderPriceDO.getPurchaseChangeFee())).subtract(orderPriceDO.getPurchaseReturnFee()));
                        // 应付 = 采购金额 + 附加费 + 服务费
                        orderPriceDO.setPurchasePayable(orderPriceDO.getPurchaseAmount().add(orderPriceDO.getPurchaseAdditionalFee()).add(orderPriceDO.getPurchaseServiceFee()));
                        orderPriceDO.setPurchasePayment(BigDecimal.ZERO);
                        // 合计（采购）
                        purchaseAdditionalFee = purchaseAdditionalFee.add(orderPriceDO.getPurchaseAdditionalFee());
                        purchaseServiceFee = purchaseServiceFee.add(orderPriceDO.getPurchaseServiceFee());
                        purchaseUpgradeFee = purchaseUpgradeFee.add(orderPriceDO.getPurchaseUpgradeFee());
                        purchaseChangeFee = purchaseChangeFee.add(orderPriceDO.getPurchaseChangeFee());
                        purchaseReturnFee = purchaseReturnFee.add(orderPriceDO.getPurchaseReturnFee());
                        purchaseTicketPrice = purchaseTicketPrice.add(orderPriceDO.getPurchaseTicketPrice());
                        purchaseUsedPrice = purchaseUsedPrice.add(orderPriceDO.getPurchaseUsedPrice());
                        purchasePrice = purchasePrice.add(orderPriceDO.getPurchasePrice());
                        purchaseAirportTax = purchaseAirportTax.add(orderPriceDO.getPurchaseAirportTax());
                        purchaseUsedAirportTax = purchaseUsedAirportTax.add(orderPriceDO.getPurchaseUsedAirportTax());
                        purchaseOilTax = purchaseOilTax.add(orderPriceDO.getPurchaseOilTax());
                        purchaseUsedOilTax = purchaseUsedOilTax.add(orderPriceDO.getPurchaseUsedOilTax());
                        purchaseTax = purchaseTax.add(orderPriceDO.getPurchaseTax());
                        purchaseUsedTax = purchaseUsedTax.add(orderPriceDO.getPurchaseUsedTax());
                        purchaseAgencyFee = purchaseAgencyFee.add(orderPriceDO.getPurchaseAgencyFee());
                        purchaseBackRebateFee = purchaseBackRebateFee.add(orderPriceDO.getPurchaseBackRebateFee());
                        purchasePrizePrice = purchasePrizePrice.add(orderPriceDO.getPurchasePrizePrice());
                        purchasePrizeTax = purchasePrizeTax.add(orderPriceDO.getPurchasePrizeTax());
                        purchaseAmount = purchaseAmount.add(orderPriceDO.getPurchaseAmount());
                        purchasePayable = purchasePayable.add(orderPriceDO.getPurchasePayable());
                        priceDOS.add(orderPriceDO);
                    }
                }
            }
        }
        // 保存价格信息
        airOrderPriceMapper.insertBatch(priceDOS);

        // 保存PNR日志
        if (StrUtil.isNotBlank(issuedReqVO.getPnr()) && StrUtil.isNotBlank(issuedReqVO.getPnrContent())) {
            AirOrderPnrLogDO pnrLogDO = new AirOrderPnrLogDO();
            pnrLogDO.setOrderId(order.getId());
            pnrLogDO.setPnr(issuedReqVO.getPnr());
            pnrLogDO.setContent(issuedReqVO.getPnrContent());
            airOrderPnrLogMapper.insert(pnrLogDO);
        }

        // 保存订单
        order.setSaleAdditionalFee(saleAdditionalFee);
        order.setSaleServiceFee(saleServiceFee);
        order.setSaleUpgradeFee(saleUpgradeFee);
        order.setSaleChangeFee(saleChangeFee);
        order.setSaleReturnFee(saleReturnFee);
        order.setSaleTicketPrice(saleTicketPrice);
        order.setSaleUsedPrice(saleUsedPrice);
        order.setSalePrice(salePrice);
        order.setSaleAirportTax(saleAirportTax);
        order.setSaleUsedAirportTax(saleUsedAirportTax);
        order.setSaleOilTax(saleOilTax);
        order.setSaleUsedOilTax(saleUsedOilTax);
        order.setSaleTax(saleTax);
        order.setSaleUsedTax(saleUsedTax);
        order.setSaleAgencyFee(saleAgencyFee);
        order.setSaleBackRebateFee(saleBackRebateFee);
        order.setSalePrizePrice(salePrizePrice);
        order.setSalePrizeTax(salePrizeTax);
        order.setSaleAmount(saleAmount);
        order.setSaleReceivable(saleReceivable);
        order.setSaleReceipts(BigDecimal.ZERO);
        order.setPurchaseAdditionalFee(purchaseAdditionalFee);
        order.setPurchaseServiceFee(purchaseServiceFee);
        order.setPurchaseUpgradeFee(purchaseUpgradeFee);
        order.setPurchaseChangeFee(purchaseChangeFee);
        order.setPurchaseReturnFee(purchaseReturnFee);
        order.setPurchaseTicketPrice(purchaseTicketPrice);
        order.setPurchaseUsedPrice(purchaseUsedPrice);
        order.setPurchasePrice(purchasePrice);
        order.setPurchaseAirportTax(purchaseAirportTax);
        order.setPurchaseOilTax(purchaseOilTax);
        order.setPurchaseTax(purchaseTax);
        order.setPurchaseUsedTax(purchaseUsedTax);
        order.setPurchaseAgencyFee(purchaseAgencyFee);
        order.setPurchaseBackRebateFee(purchaseBackRebateFee);
        order.setPurchasePrizePrice(purchasePrizePrice);
        order.setPurchasePrizeTax(purchasePrizeTax);
        order.setPurchaseAmount(purchaseAmount);
        order.setPurchasePayable(purchasePayable);
        order.setPurchasePayment(BigDecimal.ZERO);
        airOrderMapper.update(order, new LambdaUpdateWrapper<AirOrderDO>()
                .set(AirOrderDO::getLocked, false)
                .set(AirOrderDO::getLockUserId, null)
                .set(AirOrderDO::getLockDeptId, null)
                .set(AirOrderDO::getLockTime, null)
                .eq(AirOrderDO::getId, order.getId()));

        // 订单挂账
        OrderPaySuspenseAccountReqVO orderPaySuspenseAccountReqVO = new OrderPaySuspenseAccountReqVO();
        orderPaySuspenseAccountReqVO.setCustomerId(order.getCustomerId());
        orderPaySuspenseAccountReqVO.setPayUserId(order.getIssueUserId());
        orderPaySuspenseAccountReqVO.setProductType(ProductTypeEnum.AIR.getType());
        orderPaySuspenseAccountReqVO.setOrderId(order.getId());
        orderPaySuspenseAccountReqVO.setOrderNo(order.getNo());
        if (AirOrderTypeEnum.isReturn(order.getType())) {
            orderPaySuspenseAccountReqVO.setType(BasicOrderPayTypeEnum.REFUND.getType());
        } else {
            orderPaySuspenseAccountReqVO.setType(BasicOrderPayTypeEnum.RECEIVABLE.getType());
        }
        orderPaySuspenseAccountReqVO.setAmount(order.getSaleReceivable());
        orderPaySuspenseAccountReqVO.setPayTime(LocalDateTime.now());
        orderPaySuspenseAccountReqVO.setRemark(null);
        orderPayService.suspenseAccount(orderPaySuspenseAccountReqVO);
        // 返回
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long applyChangeOrder(AirOrderApplyChangeReqVO applyChangeReqVO) {
        // 校验原单存在
        AirOrderDO originAirOrderDO = validateOrderExists(applyChangeReqVO.getOriginOrderId());
        // 校验原单锁单（分销不锁单）
        if (!ClientTypeEnum.isDistribution(applyChangeReqVO.getClientType())) {
            AdminUserDO user = adminUserMapper.selectById(WebFrameworkUtils.getLoginUserId());
            if (!originAirOrderDO.getLocked()) {
                throw exception(AIR_ORDER_NOT_LOCKER_NOT_ALLOW_APPLY_CHANGE);
            } else {
                if (!Objects.equals(originAirOrderDO.getLockUserId(), user.getId())) {
                    AdminUserDO lockUser = adminUserMapper.selectById(originAirOrderDO.getLockUserId());
                    throw exception(AIR_ORDER_NOT_LOCKER_NOT_ALLOW_UNLOCK, lockUser.getNickname());
                }
            }
        }
        // 校验原单状态
        if (!AirOrderStatusEnum.isIssued(originAirOrderDO.getStatus())) {
            throw exception(AIR_ORDER_NOT_ISSUED_NOT_ALLOW_APPLY_CHANGE);
        }

        // 当前用户
        AdminUserDO loginUser = adminUserMapper.selectById(WebFrameworkUtils.getLoginUserId());
        // 客户
        CustomerDO customerDO = Optional.ofNullable(customerMapper.selectById(originAirOrderDO.getCustomerId())).orElseThrow(() -> exception(CUSTOMER_NOT_EXISTS));
//        // 配送员
//        AdminUserDO deliveryUser = Optional.ofNullable(adminUserMapper.selectById(applyChangeReqVO.getDeliveryUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_DELIVERY_USER_NOT_EXISTS));
        // 销售支付方式
        Long salePayTypeId = null;
        TenantPaySubjectDO saleTenantPaySubjectDO = tenantPaySubjectMapper.selectById(applyChangeReqVO.getSalePaySubjectId());
        if (saleTenantPaySubjectDO == null) {
            PaySubjectDO salePaySubjectDO = paySubjectMapper.selectById(applyChangeReqVO.getSalePaySubjectId());
            if (salePaySubjectDO == null) {
                throw exception(PAY_SUBJECT_NOT_EXISTS);
            }
            salePayTypeId = salePaySubjectDO.getPayTypeId();
        } else {
            salePayTypeId = saleTenantPaySubjectDO.getPayTypeId();
        }
        // 采购支付方式
        Long purchasePayTypeId = null;
        TenantPaySubjectDO purchaseTenantPaySubjectDO = tenantPaySubjectMapper.selectById(applyChangeReqVO.getSalePaySubjectId());
        if (purchaseTenantPaySubjectDO == null) {
            PaySubjectDO purchasePaySubjectDO = paySubjectMapper.selectById(applyChangeReqVO.getSalePaySubjectId());
            if (purchasePaySubjectDO == null) {
                throw exception(PAY_SUBJECT_NOT_EXISTS);
            }
            purchasePayTypeId = purchasePaySubjectDO.getPayTypeId();
        } else {
            purchasePayTypeId = saleTenantPaySubjectDO.getPayTypeId();
        }

        // 订单信息
        long orderId = IdWorker.getId();
        // 生成编号
        String no = AirOrderUtils.getNo(orderId, AirOrderTypeEnum.CHANGE.getType());
        // 校验
        validateOrderForCreateOrUpdate(null, no, applyChangeReqVO.getPnr());
        AirOrderDO order = BeanUtils.toBean(applyChangeReqVO, AirOrderDO.class);
        order.setId(orderId);
        order.setNo(no);
        order.setOriginOrderNo(originAirOrderDO.getNo());
        // 拷贝原单信息
        order.setCustomerId(originAirOrderDO.getCustomerId());
        order.setScopeType(originAirOrderDO.getScopeType());
        order.setSalesmanUserId(originAirOrderDO.getSalesmanUserId());
        order.setSalesmanDeptId(originAirOrderDO.getSalesmanDeptId());
        order.setSourceType(originAirOrderDO.getSourceType());
        // 基础信息
        order.setType(AirOrderTypeEnum.CHANGE.getType());
        order.setDeptId(loginUser.getDeptId());
        order.setPassengerNum(applyChangeReqVO.getPassengers().size());
        order.setCustomerNo(customerDO.getNo());
        order.setCustomerName(customerDO.getName());
        order.setSaleSettleType(customerDO.getSettleType());
        order.setBookUserId(loginUser.getId());
        order.setBookDeptId(loginUser.getDeptId());
        order.setBookTime(LocalDateTime.now());
        order.setDispatchUserId(loginUser.getId()); // todo
        order.setDispatchDeptId(loginUser.getDeptId()); // todo
        order.setDispatchTime(LocalDateTime.now()); // todo
//        order.setDeliveryDeptId(deliveryUser.getDeptId());
        order.setSalePayTypeId(salePayTypeId);
        order.setSalePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
        order.setSalePayOnline(false);
        order.setPurchasePayTypeId(purchasePayTypeId);
        order.setPurchasePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
        order.setPurchasePayOnline(false);
        if (SettleTypeEnum.MONTHLY.getType().equals(customerDO.getSettleType()) && customerDO.getSettlePeriodId() != null) {
            SettlePeriodCalculateRespVO calculateRespVO = settlePeriodService.calculate(new SettlePeriodCalculateReqVO(customerDO.getSettlePeriodId(), order.getBookTime().toLocalDate()));
            order.setSaleReconcileDate(calculateRespVO.getReconcileDate());
            order.setSaleSettleDate(calculateRespVO.getSettleDate());
        }
//        order.setPurchaseReconcileDate(LocalDate.now()); // todo
//        order.setPurchaseSettleDate(LocalDate.now()); // todo
        order.setChangeStatus(AirOrderChangeStatusEnum.WAIT_CHANGE.getStatus());
        order.setReturnStatus(AirOrderReturnStatusEnum.WAIT_RETURN.getStatus());
        order.setAdjustStatus(AirOrderAdjustStatusEnum.WAIT_ADJUST.getStatus());
        order.setAuditStatus(AirOrderAuditStatusEnum.WAIT_AUDIT.getStatus());
        if (ClientTypeEnum.isDistribution(applyChangeReqVO.getClientType())) {
            order.setStatus(AirChangeOrderStatusEnum.WAIT_AUDIT.getStatus());
        } else {
            order.setStatus(AirChangeOrderStatusEnum.NEW.getStatus());
        }

        // 行程信息
        List<AirOrderRouteRespVO> originAirOrderRouteRespVOS = airOrderRouteMapper.selectByOrderId(originAirOrderDO.getId());
        Map<Long, AirOrderRouteRespVO> originAirOrderRouteRespMap = originAirOrderRouteRespVOS.stream().collect(Collectors.toMap(AirOrderRouteRespVO::getId, v -> v, (v1, v2) -> v1));
        List<AirOrderRouteDO> airOrderRouteDOS = new ArrayList<>();
        AtomicInteger routeSerialNo = new AtomicInteger(1);
        for (AirOrderRouteApplyChangeReqVO aor : applyChangeReqVO.getRoutes()) {
            AirOrderRouteRespVO airOrderRouteRespVO = originAirOrderRouteRespMap.get(aor.getOriginOrderRouteId());
            if (airOrderRouteRespVO == null) {
                throw exception(AIR_ORDER_APPLY_ROUTE_ERROR_NOT_ALLOW_APPLY_CHANGE);
            }
            AirOrderRouteDO airOrderRouteDO = BeanUtils.toBean(airOrderRouteRespVO, AirOrderRouteDO.class, p -> {
                p.setId(null);
                p.setOrderId(orderId);
                p.setSerialNo(routeSerialNo.getAndIncrement());
                p.setOriginOrderRouteId(aor.getOriginOrderRouteId());
                p.setCreator(null);
                p.setCreateTime(null);
                p.setUpdater(null);
                p.setUpdateTime(null);
            });
            airOrderRouteDOS.add(airOrderRouteDO);
        }
        // 保存行程
        airOrderRouteMapper.insertBatch(airOrderRouteDOS);

        // 乘客信息
        List<AirOrderPassengerDO> originAirOrderPassengerDOS = airOrderPassengerMapper.selectByOrderId(originAirOrderDO.getId());
        Map<Long, AirOrderPassengerDO> originAirOrderPassengerMap = originAirOrderPassengerDOS.stream().collect(Collectors.toMap(AirOrderPassengerDO::getId, v -> v, (v1, v2) -> v1));
        List<AirOrderPassengerDO> airOrderPassengerDOS = new ArrayList<>();
        int passengerSerialNo = 1;
        for (AirOrderPassengerApplyChangeReqVO aop : applyChangeReqVO.getPassengers()) {
            AirOrderPassengerDO airOrderPassengerDO = originAirOrderPassengerMap.get(aop.getOriginOrderPassengerId());
            if (airOrderPassengerDO == null) {
                throw exception(AIR_ORDER_APPLY_PASSENGER_ERROR_NOT_ALLOW_APPLY_CHANGE);
            }
            airOrderPassengerDO.setId(null);
            airOrderPassengerDO.setOrderId(orderId);
            airOrderPassengerDO.setSerialNo(passengerSerialNo);
            airOrderPassengerDO.setOriginOrderPassengerId(aop.getOriginOrderPassengerId());
            airOrderPassengerDO.setSendSms(aop.getSendSms());
            airOrderPassengerDO.setCreator(null);
            airOrderPassengerDO.setCreateTime(null);
            airOrderPassengerDO.setUpdater(null);
            airOrderPassengerDO.setUpdateTime(null);
            airOrderPassengerDOS.add(airOrderPassengerDO);
            passengerSerialNo++;
        }
        // 保存乘客
        airOrderPassengerMapper.insertBatch(airOrderPassengerDOS);

        // 价格汇总信息（销售）
        // 附加费
        BigDecimal saleAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal saleServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal saleUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal saleChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal saleReturnFee = BigDecimal.ZERO;
        // 费面价
        BigDecimal saleTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal saleUsedPrice = BigDecimal.ZERO;
        // 销售价
        BigDecimal salePrice = BigDecimal.ZERO;
        // 机建
        BigDecimal saleAirportTax = BigDecimal.ZERO;
        // 已用机建
        BigDecimal saleUsedAirportTax = BigDecimal.ZERO;
        // 燃油
        BigDecimal saleOilTax = BigDecimal.ZERO;
        // 已用燃油
        BigDecimal saleUsedOilTax = BigDecimal.ZERO;
        // 销售税
        BigDecimal saleTax = BigDecimal.ZERO;
        // 已用销售税
        BigDecimal saleUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal saleAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal saleBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal salePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal salePrizeTax = BigDecimal.ZERO;
        // 销售金额
        BigDecimal saleAmount = BigDecimal.ZERO;
        // 应收
        BigDecimal saleReceivable = BigDecimal.ZERO;

        // 价格汇总信息（采购）
        // 附加费
        BigDecimal purchaseAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal purchaseServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal purchaseUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal purchaseChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal purchaseReturnFee = BigDecimal.ZERO;
        // 票面价
        BigDecimal purchaseTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal purchaseUsedPrice = BigDecimal.ZERO;
        // 采购价
        BigDecimal purchasePrice = BigDecimal.ZERO;
        // 机建税
        BigDecimal purchaseAirportTax = BigDecimal.ZERO;
        // 已用机建税
        BigDecimal purchaseUsedAirportTax = BigDecimal.ZERO;
        // 燃油税
        BigDecimal purchaseOilTax = BigDecimal.ZERO;
        // 已用燃油税
        BigDecimal purchaseUsedOilTax = BigDecimal.ZERO;
        // 采购税
        BigDecimal purchaseTax = BigDecimal.ZERO;
        // 已用采购税
        BigDecimal purchaseUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal purchaseAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal purchaseBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal purchasePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal purchasePrizeTax = BigDecimal.ZERO;
        // 采购金额
        BigDecimal purchaseAmount = BigDecimal.ZERO;
        // 应付
        BigDecimal purchasePayable = BigDecimal.ZERO;

        // 价格信息
        // 原单价格
        List<AirOrderPriceDO> updateOriginAirOrderPriceDOS = new ArrayList<>();
        List<AirOrderPriceDO> originAirOrderPriceDOS = airOrderPriceMapper.selectByOrderId(originAirOrderDO.getId());
        Map<Long, AirOrderPriceDO> originAirOrderPriceMap = originAirOrderPriceDOS.stream().collect(Collectors.toMap(p -> p.getId(), v -> v, (v1, v2) -> v1));
        Map<Long, AirOrderRouteDO> routeMap = airOrderRouteDOS.stream().collect(Collectors.toMap(p -> p.getOriginOrderRouteId(), v -> v, (v1, v2) -> v1));
        Map<Long, AirOrderPassengerDO> passengerMap = airOrderPassengerDOS.stream().collect(Collectors.toMap(p -> p.getOriginOrderPassengerId(), v -> v, (v1, v2) -> v1));
        List<AirOrderPriceDO> priceDOS = new ArrayList<>();
        for (AirOrderPriceApplyChangeReqVO opr : applyChangeReqVO.getPrices()) {
            AirOrderPriceDO originAirOrderPriceDO = originAirOrderPriceMap.get(opr.getOriginOrderPriceId());
            if (originAirOrderPriceDO == null) {
                throw exception(AIR_ORDER_APPLY_PRICE_ERROR_NOT_ALLOW_APPLY_CHANGE);
            }
            // 已改签原价格
            updateOriginAirOrderPriceDOS.add(originAirOrderPriceDO);

            AirOrderPriceDO orderPriceDO = BeanUtils.toBean(opr, AirOrderPriceDO.class);
            // 关联字段
            orderPriceDO.setOrderId(orderId);
            orderPriceDO.setOrderRouteId(routeMap.get(originAirOrderPriceDO.getOrderRouteId()).getId());
            orderPriceDO.setOrderPassengerId(passengerMap.get(originAirOrderPriceDO.getOrderPassengerId()).getId());
            // 拷贝原单信息
//            orderPriceDO.setAirlineIssueNo(originAirOrderPriceDO.getAirlineIssueNo());
//            orderPriceDO.setTicketNo(originAirOrderPriceDO.getTicketNo());
//            orderPriceDO.setTicketLastNo(originAirOrderPriceDO.getTicketLastNo());
//            orderPriceDO.setTicketVendingMachineNo(originAirOrderPriceDO.getTicketVendingMachineNo());
            // 价格（销售）
            orderPriceDO.setSaleUsedPrice(BigDecimal.ZERO);
            orderPriceDO.setSaleUsedAirportTax(BigDecimal.ZERO);
            orderPriceDO.setSaleUsedOilTax(BigDecimal.ZERO);
            orderPriceDO.setSaleUsedTax(BigDecimal.ZERO);
            orderPriceDO.setSaleReturnFeeRate(BigDecimal.ZERO);
            orderPriceDO.setSaleReturnFee(BigDecimal.ZERO);
//            orderPriceDO.setSaleTicketPrice(originAirOrderPriceDO.getSaleTicketPrice());
//            orderPriceDO.setSalePrice(originAirOrderPriceDO.getSalePrice());
//            orderPriceDO.setSaleAirportTax(originAirOrderPriceDO.getSaleAirportTax());
//            orderPriceDO.setSaleOilTax(originAirOrderPriceDO.getSaleOilTax());
//            orderPriceDO.setSaleTax(originAirOrderPriceDO.getSaleTax());
//            orderPriceDO.setSaleUpgradeFee(originAirOrderPriceDO.getSaleUpgradeFee());
//            orderPriceDO.setSaleChangeFee(originAirOrderPriceDO.getSaleChangeFee());
            // 价格（采购）
            orderPriceDO.setPurchaseUsedPrice(BigDecimal.ZERO);
            orderPriceDO.setPurchaseUsedAirportTax(BigDecimal.ZERO);
            orderPriceDO.setPurchaseUsedOilTax(BigDecimal.ZERO);
            orderPriceDO.setPurchaseUsedTax(BigDecimal.ZERO);
            orderPriceDO.setPurchaseReturnFeeRate(BigDecimal.ZERO);
            orderPriceDO.setPurchaseReturnFee(BigDecimal.ZERO);
//            orderPriceDO.setPurchaseTicketPrice(originAirOrderPriceDO.getPurchaseTicketPrice());
//            orderPriceDO.setPurchasePrice(originAirOrderPriceDO.getPurchasePrice());
//            orderPriceDO.setPurchaseAirportTax(originAirOrderPriceDO.getPurchaseAirportTax());
//            orderPriceDO.setPurchaseOilTax(originAirOrderPriceDO.getPurchaseOilTax());
//            orderPriceDO.setPurchaseTax(originAirOrderPriceDO.getPurchaseTax());
//            orderPriceDO.setPurchaseUpgradeFee(originAirOrderPriceDO.getPurchaseUpgradeFee());
//            orderPriceDO.setPurchaseChangeFee(originAirOrderPriceDO.getPurchaseUpgradeFee());
            // 基础信息
            orderPriceDO.setChangeStatus(AirOrderChangeStatusEnum.WAIT_CHANGE.getStatus());
            orderPriceDO.setReturnStatus(AirOrderReturnStatusEnum.WAIT_RETURN.getStatus());
            orderPriceDO.setAdjustStatus(AirOrderAdjustStatusEnum.WAIT_ADJUST.getStatus());
            orderPriceDO.setPurchaseId(order.getPurchaseId());
            orderPriceDO.setPurchaseOrderNo(order.getPurchaseOrderNo());
            // 支付信息（销售）
            orderPriceDO.setSalePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
            orderPriceDO.setSalePaySubjectId(order.getSalePaySubjectId());
            orderPriceDO.setSalePayTypeId(order.getSalePayTypeId());
            orderPriceDO.setSalePayAccount(order.getSalePayAccount());
            orderPriceDO.setSalePayOrderNo(order.getSalePayOrderNo());
            orderPriceDO.setSalePayTime(order.getSalePayTime());
            orderPriceDO.setSalePayOnline(order.getSalePayOnline());
            // 支付信息（采购）
            orderPriceDO.setPurchasePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
            orderPriceDO.setPurchasePaySubjectId(order.getPurchasePaySubjectId());
            orderPriceDO.setPurchasePayTypeId(order.getPurchasePayTypeId());
            orderPriceDO.setPurchasePayAccount(order.getPurchasePayAccount());
            orderPriceDO.setPurchasePayOrderNo(order.getPurchasePayOrderNo());
            orderPriceDO.setPurchasePayTime(order.getPurchasePayTime());
            orderPriceDO.setPurchasePayOnline(order.getPurchasePayOnline());

            // 价格（销售）
            // 销售金额 = 销售价 - 已用票价 + 销售税 + 升舱费 + 改期费 - 退票费
            orderPriceDO.setSaleAmount(orderPriceDO.getSalePrice().subtract(orderPriceDO.getSaleUsedPrice()).add(orderPriceDO.getSaleTax()).add(orderPriceDO.getSaleUpgradeFee().add(orderPriceDO.getSaleChangeFee())).subtract(orderPriceDO.getSaleReturnFee()));
            // 应收 = 销售金额 + 附加费 + 服务费
            orderPriceDO.setSaleReceivable(orderPriceDO.getSaleAmount().add(orderPriceDO.getSaleAdditionalFee()).add(orderPriceDO.getSaleServiceFee()));
            orderPriceDO.setSaleReceipts(BigDecimal.ZERO);
            // 合计（销售）
            saleAdditionalFee = saleAdditionalFee.add(orderPriceDO.getSaleAdditionalFee());
            saleServiceFee = saleServiceFee.add(orderPriceDO.getSaleServiceFee());
            saleUpgradeFee = saleUpgradeFee.add(orderPriceDO.getSaleUpgradeFee());
            saleChangeFee = saleChangeFee.add(orderPriceDO.getSaleChangeFee());
            saleReturnFee = saleReturnFee.add(orderPriceDO.getSaleReturnFee());
            saleTicketPrice = saleTicketPrice.add(orderPriceDO.getSaleTicketPrice());
            saleUsedPrice = saleUsedPrice.add(orderPriceDO.getSaleUsedPrice());
            salePrice = salePrice.add(orderPriceDO.getSalePrice());
            saleAirportTax = saleAirportTax.add(orderPriceDO.getSaleAirportTax());
            saleUsedAirportTax = saleUsedAirportTax.add(orderPriceDO.getSaleUsedAirportTax());
            saleOilTax = saleOilTax.add(orderPriceDO.getSaleOilTax());
            saleUsedOilTax = saleUsedOilTax.add(orderPriceDO.getSaleUsedOilTax());
            saleTax = saleTax.add(orderPriceDO.getSaleTax());
            saleUsedTax = saleUsedTax.add(orderPriceDO.getSaleUsedTax());
            saleAgencyFee = saleAgencyFee.add(orderPriceDO.getSaleAgencyFee());
            saleBackRebateFee = saleBackRebateFee.add(orderPriceDO.getSaleBackRebateFee());
            salePrizePrice = salePrizePrice.add(orderPriceDO.getSalePrizePrice());
            salePrizeTax = salePrizeTax.add(orderPriceDO.getSalePrizeTax());
            saleAmount = saleAmount.add(orderPriceDO.getSaleAmount());
            saleReceivable = saleReceivable.add(orderPriceDO.getSaleReceivable());

            // 价格（采购）
            orderPriceDO.setPurchaseReturnFee(BigDecimal.ZERO);
            // 采购金额 = 采购价 + 采购税（机建+燃油） + 升舱费 + 改期费 - 退票费
            orderPriceDO.setPurchaseAmount(orderPriceDO.getPurchasePrice().add(orderPriceDO.getPurchaseTax()).add(orderPriceDO.getPurchaseUpgradeFee().add(orderPriceDO.getPurchaseChangeFee())).subtract(orderPriceDO.getPurchaseReturnFee()));
            // 应付 = 采购金额 + 附加费 + 服务费
            orderPriceDO.setPurchasePayable(orderPriceDO.getPurchaseAmount().add(orderPriceDO.getPurchaseAdditionalFee()).add(orderPriceDO.getPurchaseServiceFee()));
            orderPriceDO.setPurchasePayment(BigDecimal.ZERO);
            // 合计（采购）
            purchaseAdditionalFee = purchaseAdditionalFee.add(orderPriceDO.getPurchaseAdditionalFee());
            purchaseServiceFee = purchaseServiceFee.add(orderPriceDO.getPurchaseServiceFee());
            purchaseUpgradeFee = purchaseUpgradeFee.add(orderPriceDO.getPurchaseUpgradeFee());
            purchaseChangeFee = purchaseChangeFee.add(orderPriceDO.getPurchaseChangeFee());
            purchaseReturnFee = purchaseReturnFee.add(orderPriceDO.getPurchaseReturnFee());
            purchaseTicketPrice = purchaseTicketPrice.add(orderPriceDO.getPurchaseTicketPrice());
            purchaseUsedPrice = purchaseUsedPrice.add(orderPriceDO.getPurchaseUsedPrice());
            purchasePrice = purchasePrice.add(orderPriceDO.getPurchasePrice());
            purchaseAirportTax = purchaseAirportTax.add(orderPriceDO.getPurchaseAirportTax());
            purchaseUsedAirportTax = purchaseUsedAirportTax.add(orderPriceDO.getPurchaseUsedAirportTax());
            purchaseOilTax = purchaseOilTax.add(orderPriceDO.getPurchaseOilTax());
            purchaseUsedOilTax = purchaseUsedOilTax.add(orderPriceDO.getPurchaseUsedOilTax());
            purchaseTax = purchaseTax.add(orderPriceDO.getPurchaseTax());
            purchaseUsedTax = purchaseUsedTax.add(orderPriceDO.getPurchaseUsedTax());
            purchaseAgencyFee = purchaseAgencyFee.add(orderPriceDO.getPurchaseAgencyFee());
            purchaseBackRebateFee = purchaseBackRebateFee.add(orderPriceDO.getPurchaseBackRebateFee());
            purchasePrizePrice = purchasePrizePrice.add(orderPriceDO.getPurchasePrizePrice());
            purchasePrizeTax = purchasePrizeTax.add(orderPriceDO.getPurchasePrizeTax());
            purchaseAmount = purchaseAmount.add(orderPriceDO.getPurchaseAmount());
            purchasePayable = purchasePayable.add(orderPriceDO.getPurchasePayable());
            priceDOS.add(orderPriceDO);
        }
        // 保存价格信息
        airOrderPriceMapper.insertBatch(priceDOS);

        // 保存PNR日志
        if (StrUtil.isNotBlank(applyChangeReqVO.getPnr()) && StrUtil.isNotBlank(applyChangeReqVO.getPnrContent())) {
            AirOrderPnrLogDO pnrLogDO = new AirOrderPnrLogDO();
            pnrLogDO.setOrderId(orderId);
            pnrLogDO.setPnr(applyChangeReqVO.getPnr());
            pnrLogDO.setContent(applyChangeReqVO.getPnrContent());
            airOrderPnrLogMapper.insert(pnrLogDO);
        }

        // 保存订单
        order.setSaleAdditionalFee(saleAdditionalFee);
        order.setSaleServiceFee(saleServiceFee);
        order.setSaleUpgradeFee(saleUpgradeFee);
        order.setSaleChangeFee(saleChangeFee);
        order.setSaleReturnFee(saleReturnFee);
        order.setSaleTicketPrice(saleTicketPrice);
        order.setSaleUsedPrice(saleUsedPrice);
        order.setSalePrice(salePrice);
        order.setSaleAirportTax(saleAirportTax);
        order.setSaleUsedAirportTax(saleUsedAirportTax);
        order.setSaleOilTax(saleOilTax);
        order.setSaleUsedOilTax(saleUsedOilTax);
        order.setSaleTax(saleTax);
        order.setSaleUsedTax(saleUsedTax);
        order.setSaleAgencyFee(saleAgencyFee);
        order.setSaleBackRebateFee(saleBackRebateFee);
        order.setSalePrizePrice(salePrizePrice);
        order.setSalePrizeTax(salePrizeTax);
        order.setSaleAmount(saleAmount);
        order.setSaleReceivable(saleReceivable);
        order.setSaleReceipts(BigDecimal.ZERO);
        order.setPurchaseAdditionalFee(purchaseAdditionalFee);
        order.setPurchaseServiceFee(purchaseServiceFee);
        order.setPurchaseUpgradeFee(purchaseUpgradeFee);
        order.setPurchaseChangeFee(purchaseChangeFee);
        order.setPurchaseReturnFee(purchaseReturnFee);
        order.setPurchaseTicketPrice(purchaseTicketPrice);
        order.setPurchaseUsedPrice(purchaseUsedPrice);
        order.setPurchasePrice(purchasePrice);
        order.setPurchaseAirportTax(purchaseAirportTax);
        order.setPurchaseOilTax(purchaseOilTax);
        order.setPurchaseTax(purchaseTax);
        order.setPurchaseUsedTax(purchaseUsedTax);
        order.setPurchaseAgencyFee(purchaseAgencyFee);
        order.setPurchaseBackRebateFee(purchaseBackRebateFee);
        order.setPurchasePrizePrice(purchasePrizePrice);
        order.setPurchasePrizeTax(purchasePrizeTax);
        order.setPurchaseAmount(purchaseAmount);
        order.setPurchasePayable(purchasePayable);
        order.setPurchasePayment(BigDecimal.ZERO);
        airOrderMapper.insert(order);

        // 更新原单价格改签信息
        for (AirOrderPriceDO aop : updateOriginAirOrderPriceDOS) {
            aop.setChangeUserId(order.getFinallyChangeUserId());
            aop.setChangeType(order.getFinallyChangeType());
            aop.setChangeDeptId(order.getFinallyChangeDeptId());
            aop.setChangeTime(order.getFinallyChangeTime());
            aop.setChangeStatus(AirOrderChangeStatusEnum.CHANGED.getStatus());
        }
        airOrderPriceMapper.updateBatch(updateOriginAirOrderPriceDOS);

        // 更新原单信息
        airOrderMapper.update(new LambdaUpdateWrapper<AirOrderDO>().eq(AirOrderDO::getId, originAirOrderDO.getId())
                .set(AirOrderDO::getFinallyChangeUserId, order.getFinallyChangeUserId())
                .set(AirOrderDO::getFinallyChangeType, order.getFinallyChangeType())
                .set(AirOrderDO::getFinallyChangeDeptId, order.getFinallyChangeDeptId())
                .set(AirOrderDO::getFinallyChangeTime, order.getFinallyChangeTime())
                .set(AirOrderDO::getChangeStatus, originAirOrderPriceDOS.size() == updateOriginAirOrderPriceDOS.size() ? AirOrderChangeStatusEnum.CHANGED.getStatus() : AirOrderChangeStatusEnum.PART_CHANGE.getStatus())
                .set(AirOrderDO::getLocked, false)
                .set(AirOrderDO::getLockUserId, null)
                .set(AirOrderDO::getLockDeptId, null)
                .set(AirOrderDO::getLockTime, null)
        );
        // 返回
        return order.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long applyReturnOrder(AirOrderApplyReturnReqVO applyReturnReqVO) {
        // 校验原单存在
        AirOrderDO originAirOrderDO = validateOrderExists(applyReturnReqVO.getOriginOrderId());
        // 校验原单锁单（分销不锁单）
        if (!ClientTypeEnum.isDistribution(applyReturnReqVO.getClientType())) {
            AdminUserDO user = adminUserMapper.selectById(WebFrameworkUtils.getLoginUserId());
            if (!originAirOrderDO.getLocked()) {
                throw exception(AIR_ORDER_NOT_LOCKER_NOT_ALLOW_APPLY_RETURN);
            } else {
                if (!Objects.equals(originAirOrderDO.getLockUserId(), user.getId())) {
                    AdminUserDO lockUser = adminUserMapper.selectById(originAirOrderDO.getLockUserId());
                    throw exception(AIR_ORDER_NOT_LOCKER_NOT_ALLOW_UNLOCK, lockUser.getNickname());
                }
            }
        }
        // 校验原单状态
        if (!AirOrderStatusEnum.isIssued(originAirOrderDO.getStatus())) {
            throw exception(AIR_ORDER_NOT_ISSUED_NOT_ALLOW_APPLY_CHANGE);
        }

        // 当前用户
        AdminUserDO loginUser = adminUserMapper.selectById(WebFrameworkUtils.getLoginUserId());
        // 客户
        CustomerDO customerDO = Optional.ofNullable(customerMapper.selectById(originAirOrderDO.getCustomerId())).orElseThrow(() -> exception(CUSTOMER_NOT_EXISTS));
//        // 配送员
//        AdminUserDO deliveryUser = Optional.ofNullable(adminUserMapper.selectById(applyReturnReqVO.getDeliveryUserId())).orElseThrow(() -> exception(AIR_ORDER_CREATE_DELIVERY_USER_NOT_EXISTS));
        // 销售支付方式
        Long salePayTypeId = null;
        TenantPaySubjectDO saleTenantPaySubjectDO = tenantPaySubjectMapper.selectById(applyReturnReqVO.getSalePaySubjectId());
        if (saleTenantPaySubjectDO == null) {
            PaySubjectDO salePaySubjectDO = paySubjectMapper.selectById(applyReturnReqVO.getSalePaySubjectId());
            if (salePaySubjectDO == null) {
                throw exception(PAY_SUBJECT_NOT_EXISTS);
            }
            salePayTypeId = salePaySubjectDO.getPayTypeId();
        } else {
            salePayTypeId = saleTenantPaySubjectDO.getPayTypeId();
        }
        // 采购支付方式
        Long purchasePayTypeId = null;
        TenantPaySubjectDO purchaseTenantPaySubjectDO = tenantPaySubjectMapper.selectById(applyReturnReqVO.getSalePaySubjectId());
        if (purchaseTenantPaySubjectDO == null) {
            PaySubjectDO purchasePaySubjectDO = paySubjectMapper.selectById(applyReturnReqVO.getSalePaySubjectId());
            if (purchasePaySubjectDO == null) {
                throw exception(PAY_SUBJECT_NOT_EXISTS);
            }
            purchasePayTypeId = purchasePaySubjectDO.getPayTypeId();
        } else {
            purchasePayTypeId = saleTenantPaySubjectDO.getPayTypeId();
        }

        // 订单信息
        long orderId = IdWorker.getId();
        // 生成编号
        String no = AirOrderUtils.getNo(orderId, AirOrderTypeEnum.RETURN.getType());
        // 校验
        validateOrderForCreateOrUpdate(null, no, null);
        AirOrderDO order = BeanUtils.toBean(applyReturnReqVO, AirOrderDO.class);
        order.setId(orderId);
        order.setNo(no);
        order.setOriginOrderNo(originAirOrderDO.getNo());
        // 拷贝原单信息
        order.setCustomerId(originAirOrderDO.getCustomerId());
        order.setScopeType(originAirOrderDO.getScopeType());
        order.setSalesmanUserId(originAirOrderDO.getSalesmanUserId());
        order.setSalesmanDeptId(originAirOrderDO.getSalesmanDeptId());
        order.setSourceType(originAirOrderDO.getSourceType());
        order.setTicketType(originAirOrderDO.getTicketType());
        order.setPurchaseId(originAirOrderDO.getPurchaseId());
        order.setPurchaseOrderNo(originAirOrderDO.getPurchaseOrderNo());
        order.setPurchasePaySubjectId(originAirOrderDO.getPurchasePaySubjectId());
        order.setIssueOffice(originAirOrderDO.getIssueOffice());
        // 基础信息
        order.setType(AirOrderTypeEnum.RETURN.getType());
        order.setDeptId(loginUser.getDeptId());
        order.setPassengerNum(applyReturnReqVO.getPassengers().size());
        order.setCustomerNo(customerDO.getNo());
        order.setCustomerName(customerDO.getName());
        order.setSaleSettleType(customerDO.getSettleType());
        order.setBookUserId(loginUser.getId());
        order.setBookDeptId(loginUser.getDeptId());
        order.setBookTime(LocalDateTime.now());
        order.setDispatchUserId(loginUser.getId()); // todo
        order.setDispatchDeptId(loginUser.getDeptId()); // todo
        order.setDispatchTime(LocalDateTime.now()); // todo
//        order.setDeliveryDeptId(deliveryUser.getDeptId());
        order.setSalePayTypeId(salePayTypeId);
        order.setSalePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
        order.setSalePayOnline(false);
        order.setPurchasePayTypeId(purchasePayTypeId);
        order.setPurchasePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
        order.setPurchasePayOnline(false);
        if (SettleTypeEnum.MONTHLY.getType().equals(customerDO.getSettleType()) && customerDO.getSettlePeriodId() != null) {
            SettlePeriodCalculateRespVO calculateRespVO = settlePeriodService.calculate(new SettlePeriodCalculateReqVO(customerDO.getSettlePeriodId(), order.getBookTime().toLocalDate()));
            order.setSaleReconcileDate(calculateRespVO.getReconcileDate());
            order.setSaleSettleDate(calculateRespVO.getSettleDate());
        }
//        order.setPurchaseReconcileDate(LocalDate.now()); // todo
//        order.setPurchaseSettleDate(LocalDate.now()); // todo
        order.setChangeStatus(AirOrderChangeStatusEnum.WAIT_CHANGE.getStatus());
        order.setReturnStatus(AirOrderReturnStatusEnum.WAIT_RETURN.getStatus());
        order.setAdjustStatus(AirOrderAdjustStatusEnum.WAIT_ADJUST.getStatus());
        order.setAuditStatus(AirOrderAuditStatusEnum.WAIT_AUDIT.getStatus());
        if (ClientTypeEnum.isDistribution(applyReturnReqVO.getClientType())) {
            order.setStatus(AirOrderStatusEnum.WAIT_AUDIT.getStatus());
        } else {
            order.setStatus(AirOrderStatusEnum.NEW.getStatus());
        }

        // 行程信息
        List<AirOrderRouteRespVO> originAirOrderRouteRespVOS = airOrderRouteMapper.selectByOrderId(originAirOrderDO.getId());
        Map<Long, AirOrderRouteRespVO> originAirOrderRouteRespMap = originAirOrderRouteRespVOS.stream().collect(Collectors.toMap(AirOrderRouteRespVO::getId, v -> v, (v1, v2) -> v1));
        List<AirOrderRouteDO> airOrderRouteDOS = new ArrayList<>();
        AtomicInteger routeSerialNo = new AtomicInteger(1);
        for (AirOrderRouteApplyReturnReqVO aor : applyReturnReqVO.getRoutes()) {
            AirOrderRouteRespVO airOrderRouteRespVO = originAirOrderRouteRespMap.get(aor.getOriginOrderRouteId());
            if (airOrderRouteRespVO == null) {
                throw exception(AIR_ORDER_APPLY_ROUTE_ERROR_NOT_ALLOW_APPLY_RETURN);
            }
            AirOrderRouteDO airOrderRouteDO = BeanUtils.toBean(airOrderRouteRespVO, AirOrderRouteDO.class, p -> {
                p.setId(null);
                p.setOrderId(orderId);
                p.setSerialNo(routeSerialNo.getAndIncrement());
                p.setOriginOrderRouteId(aor.getOriginOrderRouteId());
                p.setCreator(null);
                p.setCreateTime(null);
                p.setUpdater(null);
                p.setUpdateTime(null);
            });
            airOrderRouteDOS.add(airOrderRouteDO);
        }
        // 保存行程
        airOrderRouteMapper.insertBatch(airOrderRouteDOS);

        // 乘客信息
        List<AirOrderPassengerDO> originAirOrderPassengerDOS = airOrderPassengerMapper.selectByOrderId(originAirOrderDO.getId());
        Map<Long, AirOrderPassengerDO> originAirOrderPassengerMap = originAirOrderPassengerDOS.stream().collect(Collectors.toMap(AirOrderPassengerDO::getId, v -> v, (v1, v2) -> v1));
        List<AirOrderPassengerDO> airOrderPassengerDOS = new ArrayList<>();
        int passengerSerialNo = 1;
        for (AirOrderPassengerApplyReturnReqVO aop : applyReturnReqVO.getPassengers()) {
            AirOrderPassengerDO airOrderPassengerDO = originAirOrderPassengerMap.get(aop.getOriginOrderPassengerId());
            if (airOrderPassengerDO == null) {
                throw exception(AIR_ORDER_APPLY_PASSENGER_ERROR_NOT_ALLOW_APPLY_RETURN);
            }
            airOrderPassengerDO.setId(null);
            airOrderPassengerDO.setOrderId(orderId);
            airOrderPassengerDO.setSerialNo(passengerSerialNo);
            airOrderPassengerDO.setOriginOrderPassengerId(aop.getOriginOrderPassengerId());
            airOrderPassengerDO.setSendSms(aop.getSendSms());
            airOrderPassengerDO.setCreator(null);
            airOrderPassengerDO.setCreateTime(null);
            airOrderPassengerDO.setUpdater(null);
            airOrderPassengerDO.setUpdateTime(null);
            airOrderPassengerDOS.add(airOrderPassengerDO);
            passengerSerialNo++;
        }
        // 保存乘客
        airOrderPassengerMapper.insertBatch(airOrderPassengerDOS);

        // 价格汇总信息（销售）
        // 附加费
        BigDecimal saleAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal saleServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal saleUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal saleChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal saleReturnFee = BigDecimal.ZERO;
        // 费面价
        BigDecimal saleTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal saleUsedPrice = BigDecimal.ZERO;
        // 销售价
        BigDecimal salePrice = BigDecimal.ZERO;
        // 机建
        BigDecimal saleAirportTax = BigDecimal.ZERO;
        // 已用机建
        BigDecimal saleUsedAirportTax = BigDecimal.ZERO;
        // 燃油
        BigDecimal saleOilTax = BigDecimal.ZERO;
        // 已用燃油
        BigDecimal saleUsedOilTax = BigDecimal.ZERO;
        // 销售税
        BigDecimal saleTax = BigDecimal.ZERO;
        // 已用销售税
        BigDecimal saleUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal saleAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal saleBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal salePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal salePrizeTax = BigDecimal.ZERO;
        // 销售金额
        BigDecimal saleAmount = BigDecimal.ZERO;
        // 应收
        BigDecimal saleReceivable = BigDecimal.ZERO;

        // 价格汇总信息（采购）
        // 附加费
        BigDecimal purchaseAdditionalFee = BigDecimal.ZERO;
        // 服务费
        BigDecimal purchaseServiceFee = BigDecimal.ZERO;
        // 升舱费
        BigDecimal purchaseUpgradeFee = BigDecimal.ZERO;
        // 改期费
        BigDecimal purchaseChangeFee = BigDecimal.ZERO;
        // 退票费
        BigDecimal purchaseReturnFee = BigDecimal.ZERO;
        // 票面价
        BigDecimal purchaseTicketPrice = BigDecimal.ZERO;
        // 已用票面价
        BigDecimal purchaseUsedPrice = BigDecimal.ZERO;
        // 采购价
        BigDecimal purchasePrice = BigDecimal.ZERO;
        // 机建税
        BigDecimal purchaseAirportTax = BigDecimal.ZERO;
        // 已用机建税
        BigDecimal purchaseUsedAirportTax = BigDecimal.ZERO;
        // 燃油税
        BigDecimal purchaseOilTax = BigDecimal.ZERO;
        // 已用燃油税
        BigDecimal purchaseUsedOilTax = BigDecimal.ZERO;
        // 采购税
        BigDecimal purchaseTax = BigDecimal.ZERO;
        // 已用采购税
        BigDecimal purchaseUsedTax = BigDecimal.ZERO;
        // 代理费
        BigDecimal purchaseAgencyFee = BigDecimal.ZERO;
        // 后返费
        BigDecimal purchaseBackRebateFee = BigDecimal.ZERO;
        // 记奖价
        BigDecimal purchasePrizePrice = BigDecimal.ZERO;
        // 记奖税
        BigDecimal purchasePrizeTax = BigDecimal.ZERO;
        // 采购金额
        BigDecimal purchaseAmount = BigDecimal.ZERO;
        // 应付
        BigDecimal purchasePayable = BigDecimal.ZERO;

        // 价格信息
        // 原单价格
        List<AirOrderPriceDO> updateOriginAirOrderPriceDOS = new ArrayList<>();
        List<AirOrderPriceDO> originAirOrderPriceDOS = airOrderPriceMapper.selectByOrderId(originAirOrderDO.getId());
        Map<Long, AirOrderPriceDO> originAirOrderPriceMap = originAirOrderPriceDOS.stream().collect(Collectors.toMap(p -> p.getId(), v -> v, (v1, v2) -> v1));
        Map<Long, AirOrderRouteDO> routeMap = airOrderRouteDOS.stream().collect(Collectors.toMap(p -> p.getOriginOrderRouteId(), v -> v, (v1, v2) -> v1));
        Map<Long, AirOrderPassengerDO> passengerMap = airOrderPassengerDOS.stream().collect(Collectors.toMap(p -> p.getOriginOrderPassengerId(), v -> v, (v1, v2) -> v1));
        List<AirOrderPriceDO> priceDOS = new ArrayList<>();
        for (AirOrderPriceApplyReturnReqVO opr : applyReturnReqVO.getPrices()) {
            AirOrderPriceDO originAirOrderPriceDO = originAirOrderPriceMap.get(opr.getOriginOrderPriceId());
            if (originAirOrderPriceDO == null) {
                throw exception(AIR_ORDER_APPLY_PRICE_ERROR_NOT_ALLOW_APPLY_RETURN);
            }
            // 已退票原价格
            updateOriginAirOrderPriceDOS.add(originAirOrderPriceDO);

            AirOrderPriceDO orderPriceDO = BeanUtils.toBean(opr, AirOrderPriceDO.class);
            // 关联字段
            orderPriceDO.setOrderId(orderId);
            orderPriceDO.setOrderRouteId(routeMap.get(originAirOrderPriceDO.getOrderRouteId()).getId());
            orderPriceDO.setOrderPassengerId(passengerMap.get(originAirOrderPriceDO.getOrderPassengerId()).getId());
            // 拷贝原单信息
            orderPriceDO.setAirlineIssueNo(originAirOrderPriceDO.getAirlineIssueNo());
            orderPriceDO.setTicketNo(originAirOrderPriceDO.getTicketNo());
            orderPriceDO.setTicketLastNo(originAirOrderPriceDO.getTicketLastNo());
            orderPriceDO.setTicketVendingMachineNo(originAirOrderPriceDO.getTicketVendingMachineNo());
            // 拷贝原单价格（销售）
            orderPriceDO.setSaleTicketPrice(originAirOrderPriceDO.getSaleTicketPrice());
            orderPriceDO.setSalePrice(originAirOrderPriceDO.getSalePrice());
            orderPriceDO.setSaleAirportTax(originAirOrderPriceDO.getSaleAirportTax());
            orderPriceDO.setSaleOilTax(originAirOrderPriceDO.getSaleOilTax());
            orderPriceDO.setSaleTax(originAirOrderPriceDO.getSaleTax());
            orderPriceDO.setSaleUpgradeFee(originAirOrderPriceDO.getSaleUpgradeFee());
            orderPriceDO.setSaleChangeFee(originAirOrderPriceDO.getSaleChangeFee());
            // 拷贝原单价格（采购）
            orderPriceDO.setPurchaseTicketPrice(originAirOrderPriceDO.getPurchaseTicketPrice());
            orderPriceDO.setPurchasePrice(originAirOrderPriceDO.getPurchasePrice());
            orderPriceDO.setPurchaseAirportTax(originAirOrderPriceDO.getPurchaseAirportTax());
            orderPriceDO.setPurchaseOilTax(originAirOrderPriceDO.getPurchaseOilTax());
            orderPriceDO.setPurchaseTax(originAirOrderPriceDO.getPurchaseTax());
            orderPriceDO.setPurchaseUpgradeFee(originAirOrderPriceDO.getPurchaseUpgradeFee());
            orderPriceDO.setPurchaseChangeFee(originAirOrderPriceDO.getPurchaseUpgradeFee());
            // 基础信息
            orderPriceDO.setChangeStatus(AirOrderChangeStatusEnum.WAIT_CHANGE.getStatus());
            orderPriceDO.setReturnStatus(AirOrderReturnStatusEnum.WAIT_RETURN.getStatus());
            orderPriceDO.setAdjustStatus(AirOrderAdjustStatusEnum.WAIT_ADJUST.getStatus());
            orderPriceDO.setPurchaseId(order.getPurchaseId());
            orderPriceDO.setPurchaseOrderNo(order.getPurchaseOrderNo());
            // 支付信息（销售）
            orderPriceDO.setSalePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
            orderPriceDO.setSalePaySubjectId(order.getSalePaySubjectId());
            orderPriceDO.setSalePayTypeId(order.getSalePayTypeId());
            orderPriceDO.setSalePayAccount(order.getSalePayAccount());
            orderPriceDO.setSalePayOrderNo(order.getSalePayOrderNo());
            orderPriceDO.setSalePayTime(order.getSalePayTime());
            orderPriceDO.setSalePayOnline(order.getSalePayOnline());
            // 支付信息（采购）
            orderPriceDO.setPurchasePayStatus(PayStatusEnum.WAIT_PAY.getStatus());
            orderPriceDO.setPurchasePaySubjectId(order.getPurchasePaySubjectId());
            orderPriceDO.setPurchasePayTypeId(order.getPurchasePayTypeId());
            orderPriceDO.setPurchasePayAccount(order.getPurchasePayAccount());
            orderPriceDO.setPurchasePayOrderNo(order.getPurchasePayOrderNo());
            orderPriceDO.setPurchasePayTime(order.getPurchasePayTime());
            orderPriceDO.setPurchasePayOnline(order.getPurchasePayOnline());

            // 价格负数转换
            AirOrderUtils.convertToMinus(orderPriceDO);

            // 价格（销售）
            // 销售金额 = 销售价 - 已用票价 + 销售税 + 升舱费 + 改期费 - 退票费
            orderPriceDO.setSaleAmount(orderPriceDO.getSalePrice().subtract(orderPriceDO.getSaleUsedPrice()).add(orderPriceDO.getSaleTax()).add(orderPriceDO.getSaleUpgradeFee().add(orderPriceDO.getSaleChangeFee())).subtract(orderPriceDO.getSaleReturnFee()));
            // 应收 = 销售金额 + 附加费 + 服务费
            orderPriceDO.setSaleReceivable(orderPriceDO.getSaleAmount().add(orderPriceDO.getSaleAdditionalFee()).add(orderPriceDO.getSaleServiceFee()));
            orderPriceDO.setSaleReceipts(BigDecimal.ZERO);
            // 合计（销售）
            saleAdditionalFee = saleAdditionalFee.add(orderPriceDO.getSaleAdditionalFee());
            saleServiceFee = saleServiceFee.add(orderPriceDO.getSaleServiceFee());
            saleUpgradeFee = saleUpgradeFee.add(orderPriceDO.getSaleUpgradeFee());
            saleChangeFee = saleChangeFee.add(orderPriceDO.getSaleChangeFee());
            saleReturnFee = saleReturnFee.add(orderPriceDO.getSaleReturnFee());
            saleTicketPrice = saleTicketPrice.add(orderPriceDO.getSaleTicketPrice());
            saleUsedPrice = saleUsedPrice.add(orderPriceDO.getSaleUsedPrice());
            salePrice = salePrice.add(orderPriceDO.getSalePrice());
            saleAirportTax = saleAirportTax.add(orderPriceDO.getSaleAirportTax());
            saleUsedAirportTax = saleUsedAirportTax.add(orderPriceDO.getSaleUsedAirportTax());
            saleOilTax = saleOilTax.add(orderPriceDO.getSaleOilTax());
            saleUsedOilTax = saleUsedOilTax.add(orderPriceDO.getSaleUsedOilTax());
            saleTax = saleTax.add(orderPriceDO.getSaleTax());
            saleUsedTax = saleUsedTax.add(orderPriceDO.getSaleUsedTax());
            saleAgencyFee = saleAgencyFee.add(orderPriceDO.getSaleAgencyFee());
            saleBackRebateFee = saleBackRebateFee.add(orderPriceDO.getSaleBackRebateFee());
            salePrizePrice = salePrizePrice.add(orderPriceDO.getSalePrizePrice());
            salePrizeTax = salePrizeTax.add(orderPriceDO.getSalePrizeTax());
            saleAmount = saleAmount.add(orderPriceDO.getSaleAmount());
            saleReceivable = saleReceivable.add(orderPriceDO.getSaleReceivable());

            // 价格（采购）
            orderPriceDO.setPurchaseReturnFee(BigDecimal.ZERO);
            // 采购金额 = 采购价 + 采购税（机建+燃油） + 升舱费 + 改期费 - 退票费
            orderPriceDO.setPurchaseAmount(orderPriceDO.getPurchasePrice().add(orderPriceDO.getPurchaseTax()).add(orderPriceDO.getPurchaseUpgradeFee().add(orderPriceDO.getPurchaseChangeFee())).subtract(orderPriceDO.getPurchaseReturnFee()));
            // 应付 = 采购金额 + 附加费 + 服务费
            orderPriceDO.setPurchasePayable(orderPriceDO.getPurchaseAmount().add(orderPriceDO.getPurchaseAdditionalFee()).add(orderPriceDO.getPurchaseServiceFee()));
            orderPriceDO.setPurchasePayment(BigDecimal.ZERO);
            // 合计（采购）
            purchaseAdditionalFee = purchaseAdditionalFee.add(orderPriceDO.getPurchaseAdditionalFee());
            purchaseServiceFee = purchaseServiceFee.add(orderPriceDO.getPurchaseServiceFee());
            purchaseUpgradeFee = purchaseUpgradeFee.add(orderPriceDO.getPurchaseUpgradeFee());
            purchaseChangeFee = purchaseChangeFee.add(orderPriceDO.getPurchaseChangeFee());
            purchaseReturnFee = purchaseReturnFee.add(orderPriceDO.getPurchaseReturnFee());
            purchaseTicketPrice = purchaseTicketPrice.add(orderPriceDO.getPurchaseTicketPrice());
            purchaseUsedPrice = purchaseUsedPrice.add(orderPriceDO.getPurchaseUsedPrice());
            purchasePrice = purchasePrice.add(orderPriceDO.getPurchasePrice());
            purchaseAirportTax = purchaseAirportTax.add(orderPriceDO.getPurchaseAirportTax());
            purchaseUsedAirportTax = purchaseUsedAirportTax.add(orderPriceDO.getPurchaseUsedAirportTax());
            purchaseOilTax = purchaseOilTax.add(orderPriceDO.getPurchaseOilTax());
            purchaseUsedOilTax = purchaseUsedOilTax.add(orderPriceDO.getPurchaseUsedOilTax());
            purchaseTax = purchaseTax.add(orderPriceDO.getPurchaseTax());
            purchaseUsedTax = purchaseUsedTax.add(orderPriceDO.getPurchaseUsedTax());
            purchaseAgencyFee = purchaseAgencyFee.add(orderPriceDO.getPurchaseAgencyFee());
            purchaseBackRebateFee = purchaseBackRebateFee.add(orderPriceDO.getPurchaseBackRebateFee());
            purchasePrizePrice = purchasePrizePrice.add(orderPriceDO.getPurchasePrizePrice());
            purchasePrizeTax = purchasePrizeTax.add(orderPriceDO.getPurchasePrizeTax());
            purchaseAmount = purchaseAmount.add(orderPriceDO.getPurchaseAmount());
            purchasePayable = purchasePayable.add(orderPriceDO.getPurchasePayable());
            priceDOS.add(orderPriceDO);
        }
        // 保存价格信息
        airOrderPriceMapper.insertBatch(priceDOS);

        // 保存订单
        order.setSaleAdditionalFee(saleAdditionalFee);
        order.setSaleServiceFee(saleServiceFee);
        order.setSaleUpgradeFee(saleUpgradeFee);
        order.setSaleChangeFee(saleChangeFee);
        order.setSaleReturnFee(saleReturnFee);
        order.setSaleTicketPrice(saleTicketPrice);
        order.setSaleUsedPrice(saleUsedPrice);
        order.setSalePrice(salePrice);
        order.setSaleAirportTax(saleAirportTax);
        order.setSaleUsedAirportTax(saleUsedAirportTax);
        order.setSaleOilTax(saleOilTax);
        order.setSaleUsedOilTax(saleUsedOilTax);
        order.setSaleTax(saleTax);
        order.setSaleUsedTax(saleUsedTax);
        order.setSaleAgencyFee(saleAgencyFee);
        order.setSaleBackRebateFee(saleBackRebateFee);
        order.setSalePrizePrice(salePrizePrice);
        order.setSalePrizeTax(salePrizeTax);
        order.setSaleAmount(saleAmount);
        order.setSaleReceivable(saleReceivable);
        order.setSaleReceipts(BigDecimal.ZERO);
        order.setPurchaseAdditionalFee(purchaseAdditionalFee);
        order.setPurchaseServiceFee(purchaseServiceFee);
        order.setPurchaseUpgradeFee(purchaseUpgradeFee);
        order.setPurchaseChangeFee(purchaseChangeFee);
        order.setPurchaseReturnFee(purchaseReturnFee);
        order.setPurchaseTicketPrice(purchaseTicketPrice);
        order.setPurchaseUsedPrice(purchaseUsedPrice);
        order.setPurchasePrice(purchasePrice);
        order.setPurchaseAirportTax(purchaseAirportTax);
        order.setPurchaseOilTax(purchaseOilTax);
        order.setPurchaseTax(purchaseTax);
        order.setPurchaseUsedTax(purchaseUsedTax);
        order.setPurchaseAgencyFee(purchaseAgencyFee);
        order.setPurchaseBackRebateFee(purchaseBackRebateFee);
        order.setPurchasePrizePrice(purchasePrizePrice);
        order.setPurchasePrizeTax(purchasePrizeTax);
        order.setPurchaseAmount(purchaseAmount);
        order.setPurchasePayable(purchasePayable);
        order.setPurchasePayment(BigDecimal.ZERO);
        airOrderMapper.insert(order);

        // 更新原单价格退票信息
        for (AirOrderPriceDO aop : updateOriginAirOrderPriceDOS) {
            aop.setReturnOrderType(order.getFinallyReturnOrderType());
            aop.setReturnUserId(order.getFinallyReturnUserId());
            aop.setReturnDeptId(order.getFinallyReturnDeptId());
            aop.setReturnTime(order.getFinallyReturnTime());
            aop.setReturnStatus(AirOrderReturnStatusEnum.RETURNED.getStatus());
        }
        airOrderPriceMapper.updateBatch(updateOriginAirOrderPriceDOS);

        // 更新原单信息
        airOrderMapper.update(new LambdaUpdateWrapper<AirOrderDO>().eq(AirOrderDO::getId, originAirOrderDO.getId())
                .set(AirOrderDO::getFinallyReturnOrderType, order.getFinallyReturnOrderType())
                .set(AirOrderDO::getFinallyReturnType, order.getFinallyReturnType())
                .set(AirOrderDO::getFinallyReturnUserId, order.getFinallyReturnUserId())
                .set(AirOrderDO::getFinallyReturnDeptId, order.getFinallyReturnDeptId())
                .set(AirOrderDO::getFinallyReturnTime, order.getFinallyReturnTime())
                .set(AirOrderDO::getReturnStatus, originAirOrderPriceDOS.size() == updateOriginAirOrderPriceDOS.size() ? AirOrderReturnStatusEnum.RETURNED.getStatus() : AirOrderReturnStatusEnum.PART_RETURN.getStatus())
                .set(AirOrderDO::getLocked, false)
                .set(AirOrderDO::getLockUserId, null)
                .set(AirOrderDO::getLockDeptId, null)
                .set(AirOrderDO::getLockTime, null)
        );
        // 返回
        return order.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancelOrder(AirOrderCancelReqVO cancelReqVO) {
        // 校验存在
        AirOrderDO airOrderDO = validateOrderExists(cancelReqVO.getId());
        if (AirOrderStatusEnum.isCanceled(airOrderDO.getStatus())) {
            throw exception(AIR_ORDER_CANCELED_NOT_ALLOW_CANCEL);
        }
        if (!AirOrderStatusEnum.isNew(airOrderDO.getStatus())) {
            throw exception(AIR_ORDER_CONFIRMED_NOT_ALLOW_CANCEL);
        }
        if (cancelReqVO.getCancelSeat()) {
            // 取消接口订单
            if (AirOrderTypeEnum.isSale(airOrderDO.getType()) || AirOrderTypeEnum.isChange(airOrderDO.getType())) {
                AirOrderCancelReqDTO airOrderCancelReqDTO = new AirOrderCancelReqDTO();
                airOrderCancelReqDTO.setChannelId(airOrderDO.getBookChannelId());
                airOrderCancelReqDTO.setOrderNo(airOrderDO.getPnr());
                AirOrderCancelRespDTO airOrderCancelRespDTO = airApiService.cancelOrder(airOrderCancelReqDTO);
                if (airOrderCancelRespDTO.getSuccess()) {
                    airOrderDO.setPnrStatus(AirPnrStatusEnum.XX.getStatus());
                }
            }
        }
        // 当前用户
        AdminUserDO loginUser = adminUserMapper.selectById(WebFrameworkUtils.getLoginUserId());
        // 更新状态
        airOrderDO.setStatus(AirDemandOrderStatusEnum.CANCELED.getStatus());
        airOrderDO.setCancelUserId(loginUser.getId());
        airOrderDO.setCancelDeptId(loginUser.getDeptId());
        airOrderDO.setCancelTime(LocalDateTime.now());
        airOrderMapper.updateById(airOrderDO);
        return true;
    }

    @Override
    public Boolean cancelOrderByPnr(Long cancelUserId, String pnr) {
        // 校验存在
        AirOrderDO airOrderDO = airOrderMapper.selectByPnr(pnr);
        if (airOrderDO == null) {
            throw exception(AIR_ORDER_NOT_EXISTS);
        }
        // 出票前取消订单并更新pnr状态，出票后只更新pnr状态
        if (AirOrderStatusEnum.isIssued(airOrderDO.getStatus())) {
            airOrderDO.setPnrStatus(AirPnrStatusEnum.XX.getStatus());
        } else {
            AdminUserDO cancelUser = adminUserMapper.selectById(cancelUserId);
            airOrderDO.setStatus(AirDemandOrderStatusEnum.CANCELED.getStatus());
            airOrderDO.setPnrStatus(AirPnrStatusEnum.XX.getStatus());
            airOrderDO.setCancelUserId(cancelUser.getId());
            airOrderDO.setCancelDeptId(cancelUser.getDeptId());
            airOrderDO.setCancelTime(LocalDateTime.now());
        }
        airOrderMapper.updateById(airOrderDO);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean lockOrder(AirOrderLockReqVO lockReqVO) {
        // 校验存在
        AirOrderDO airOrderDO = validateOrderExists(lockReqVO.getId());
        if (airOrderDO.getLocked()) {
            throw exception(AIR_ORDER_LOCKED_NOT_ALLOW_LOCK, Optional.ofNullable(adminUserMapper.selectById(airOrderDO.getLockUserId())).map(AdminUserDO::getNickname).orElse(null));
        }
        // 当前用户
        AdminUserDO user = adminUserMapper.selectById(WebFrameworkUtils.getLoginUserId());
        // 更新状态
        airOrderDO.setLocked(true);
        airOrderDO.setLockUserId(user.getId());
        airOrderDO.setLockDeptId(user.getDeptId());
        airOrderDO.setLockTime(LocalDateTime.now());
        airOrderMapper.updateById(airOrderDO);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean unlockOrder(AirOrderLockReqVO lockReqVO) {
        // 校验存在
        AirOrderDO airOrderDO = validateOrderExists(lockReqVO.getId());
        if (!airOrderDO.getLocked()) {
            throw exception(AIR_ORDER_UNLOCKED_NOT_ALLOW_UNLOCK);
        }
        // 谁锁谁解锁
        AdminUserDO user = adminUserMapper.selectById(WebFrameworkUtils.getLoginUserId());
        if (!Objects.equals(airOrderDO.getLockUserId(), user.getId())) {
            throw exception(AIR_ORDER_NOT_LOCKER_NOT_ALLOW_UNLOCK, Optional.ofNullable(adminUserMapper.selectById(airOrderDO.getLockUserId())).map(AdminUserDO::getNickname).orElse(null));
        }
        // 更新状态
        airOrderMapper.update(new LambdaUpdateWrapper<AirOrderDO>()
                .set(AirOrderDO::getLocked, false)
                .set(AirOrderDO::getLockUserId, null)
                .set(AirOrderDO::getLockDeptId, null)
                .set(AirOrderDO::getLockTime, null)
                .eq(AirOrderDO::getId, airOrderDO.getId()));
        return true;
    }

    @Override
    public AirOrderRespVO getOrder(Long id) {
        AirOrderRespVO airOrderRespVO = airOrderMapper.selectOrderById(id);
        if (airOrderRespVO != null) {
            airOrderRespVO.setRoutes(airOrderRouteMapper.selectByOrderId(id));
            airOrderRespVO.setPassengers(BeanUtils.toBean(airOrderPassengerMapper.selectByOrderId(id), AirOrderPassengerRespVO.class));
            airOrderRespVO.setPrices(BeanUtils.toBean(airOrderPriceMapper.selectByOrderId(id), AirOrderPriceRespVO.class));
            airOrderRespVO.setPnrLogs(BeanUtils.toBean(airOrderPnrLogMapper.selectByOrderId(id), AirOrderPnrLogRespVO.class));
            airOrderRespVO.setPayments(BeanUtils.toBean(orderPayService.getOrderPayList(id), OrderPayRespVO.class));
        }
        return airOrderRespVO;
    }

    @Override
    public AirOrderRespVO getOrderByNo(String no) {
        AirOrderDO airOrderDO = airOrderMapper.selectByNo(no);
        if (airOrderDO != null) {
            return getOrder(airOrderDO.getId());
        }
        return null;
    }

    @Override
    public AirOrderRespVO getOrderByPnr(String pnr) {
        AirOrderDO airOrderDO = airOrderMapper.selectByPnr(pnr);
        if (airOrderDO != null) {
            return getOrder(airOrderDO.getId());
        }
        return null;
    }

    @Override
    public PageResult<AirOrderRespVO> getOrderPage(AirOrderPageReqVO pageReqVO) {
        IPage<AirOrderRespVO> mpPage = MyBatisUtils.buildPage(pageReqVO);
        IPage<AirOrderRespVO> resPage = airOrderMapper.selectOrderPage(mpPage, pageReqVO);
        return new PageResult(resPage.getRecords(), resPage.getTotal());
    }

    private AirOrderDO validateOrderExists(Long id) {
        if (id == null) {
            return null;
        }
        AirOrderDO airOrderDO = airOrderMapper.selectById(id);
        if (airOrderDO == null) {
            throw exception(AIR_ORDER_NOT_EXISTS);
        }
        return airOrderDO;
    }

    public void validateOrderUnique(Long id, String no) {
        if (StrUtil.isBlank(no)) {
            return;
        }
        AirOrderDO airOrderDO = airOrderMapper.selectByNo(no);
        if (airOrderDO == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的用户
        if (id == null) {
            throw exception(AIR_ORDER_NO_EXISTS);
        }
        if (!airOrderDO.getId().equals(id)) {
            throw exception(AIR_ORDER_NO_EXISTS);
        }
    }

    public void validatePnrUnique(Long id, String pnr) {
        if (StrUtil.isBlank(pnr)) {
            return;
        }
        AirOrderDO airOrderDO = airOrderMapper.selectByPnr(pnr);
        if (airOrderDO == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的用户
        if (id == null) {
            throw exception(AIR_ORDER_PNR_EXISTS, pnr);
        }
        if (!airOrderDO.getId().equals(id)) {
            throw exception(AIR_ORDER_PNR_EXISTS, pnr);
        }
    }

    public AirOrderDO validateOrderForCreateOrUpdate(Long id, String no, String pnr) {
        // 校验存在
        AirOrderDO airOrderDO = validateOrderExists(id);
        // 校验唯一
        validateOrderUnique(id, no);
        // 校验编码
        validatePnrUnique(id, pnr);
        return airOrderDO;
    }

}
